These are chat archives for jdubray/sam

19th
Apr 2017
devin ivy
@devinivy
Apr 19 2017 17:33
just gave a presentation to my coworkers about the importance of state (vs. model) in the context of redux. well-received!
Fred Daoud
@foxdonut
Apr 19 2017 18:00
nice @devinivy ! :thumbsup:
devin ivy
@devinivy
Apr 19 2017 18:18
yes! thanks for all the convos over the past year :) here's a drawing as a gift...
i realize it doesn't reflect the full glory of SAM :P
we're going to add nap() here into our flow any day ;)
devin ivy
@devinivy
Apr 19 2017 18:23
i was getting the feeling that folks found connect() to be almost-useless boilerplate code, aside from passing the occasional result of a selector. i'm advocating for having meaningful code in connect(), typically in order to remove model-concepts from the view (regarding both state and action-dispatches).
Jean-Jacques Dubray
@jdubray
Apr 19 2017 18:52
wow!
devin ivy
@devinivy
Apr 19 2017 18:56
also for fun– here's the same redux app twice, one with a strong connect() factoring and one with no connect() factoring. at the top is a challenge to fix a particular bug and implement a particular feature. hoping it causes good discussion as to where code for that bug and feature oughtta live! and hopefully that the one with a strong connect() factoring feels easier to develop on. while the app is simple, this would still not be at all straightforward to many redux folk, let along new redux folk.
only dependency is redux, no react or anything like that.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:05
that's horrific (in render with connect): const state = store.getState();
devin ivy
@devinivy
Apr 19 2017 19:06
that's what the standard redux diagram would have you believe should happen
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:06
that's horrific: store.subscribe(() => ConnectedUI.render()); :-)
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:07
you need the state function in between to avoid this:
        const first = this.props.firstNumber;
        const second = this.props.secondNumber;
devin ivy
@devinivy
Apr 19 2017 19:07
the state function is essentially the first argument to connect()
does this part actually bother you? store.subscribe(() => ConnectedUI.render());
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:10
not exactly, this is the technique I used with Angular2 (pub/sub). What bothers me is the coupling between the store structure and the UI.
In Angular2 my UI Components are just waiting for props that are supplied/published by the state function.
blob
devin ivy
@devinivy
Apr 19 2017 19:12
the store and the UI are simple enough in this case that they both deal with values that are either numbers or null.
it still computes the result in the state function
rather than in the store.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:13
well technically it should be in the model :-)
devin ivy
@devinivy
Apr 19 2017 19:14
but the result would then have to stay in sync with the divisor and dividend props of the model.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:14
because you are mutating state, the state function should ony compute the state representation and invoke the "display" mechanism (which itself can be uggly, e.g. C3 graphs)
well, that's the rule, application state mutation has to be in the model.
devin ivy
@devinivy
Apr 19 2017 19:16
this is meant to emulate react-redux, though (hence connect()), so it's going to look a little different. conceptually, though, i hoped we would agree what should go in the state representation.
i guess i disagree that the result of the math necessarily belongs in the model. it can be derived from the state of the application (divisor and dividend). i find it to be worthwhile to keep the model denormalized. any state that can be derived as a pure function of the model belongs in the state representation.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:17
It depends on your point of view I guess, the model could be the operands and the result part of the "computed" properties.
devin ivy
@devinivy
Apr 19 2017 19:17
yes, that's what i would intend :point_up:
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:18
In this case it works because no other parts of the model depend on the result.
I would however argue that result is part of the structure of the system, it's a bit of a stretch to say it's part of the state representation.
For me state representation would be something like unit conversions. You don't want to bother the model with that.

Again not sure I would agree with that:

i hoped we would agree what should go in the state representation.

you really have to think in terms of "structure of the system". Take the speed of a car, you would obviously calculate it, would the speed be part of the model? or computed in the state?
devin ivy
@devinivy
Apr 19 2017 19:20
i just don't see any need to put it in the model if it can be derived as a pure function of the rest of model– and you sidestep the possibility of missing an update to one of its operands and the data getting out of sync.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:21
I understand your point, respect it, but I'd say it may not be general enough.
devin ivy
@devinivy
Apr 19 2017 19:21
for example, some data you wouldn't even be able to store in the model. consider the model for an app choosing the first two terms of a fibonacci-style sequence. it's an infinite list!
in any case, it's a small point, and this application would work well either way :)
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:24
yes, I think it's easy to reason as needed. I understand you point and less clutter in the model, the better.
devin ivy
@devinivy
Apr 19 2017 19:24
what i'm more curious is how you suggest making the connected props look less like the contents of the model.
when in reality they really are quite similar in the view and model.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:25
It illustrates well that this is a choice and there is clearly a need for the state function rather than having all this code in the model.
Clearly it's a projection, it's not so much you want to make them less connected to the model, it's more when you don't have a choice. Imagine now that you are reusing a component from a library, or built by another team. They might have a completely different set of props and options. Why would you want to model to carry that baggage? It really helps make the view components plug and play, much easier to replace when everything has been built, because you know the state function cannot mutate state, only compute.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:30
In SAM everything is designed to have no business logic in the view components whatsoever. The only logic that should be in the view components are the display logic (a smart table with pagination and search of the records currently being displayed).
devin ivy
@devinivy
Apr 19 2017 19:31
:thumbsup: we're on the same page
connect() is basically an adapter between the view and the model, so it's not technically part of the view.
Jean-Jacques Dubray
@jdubray
Apr 19 2017 19:33
yes, absolutely, that's how I saw it:
const ConnectedUI = connect(
    (state) => {

        return {
            firstNumber: state.dividend,
            secondNumber: state.divisor,
            result: state.dividend / state.divisor
        };
    },
    {
        changeFirstNumber: actions.chooseDividend,
        changeSecondNumber: actions.chooseDivisor
    }
)
(UI);
and you could perform projects as needed here to avoid that:
        const first = this.props.firstNumber;
        const second = this.props.secondNumber;
You could probably weave nap() in the connect function as well.