Modifying "parent state" from child page in an elm-spa-example-like architecture

Putting the shared state in the pages and just handing it off when creating a new page works nicely to avoid the parent data problem but introduces the potential issue that there is nothing in the data structure to express that we only have one user at a time except to the extent that we only allow one page at a time. What if things evolved in a way where we didn’t want to show only one page — e.g., what used to be a separate page turns into a panel that opens on the side? If correctness depends on there only being one logged in user, then the make-illegal-states-impossible philosophy says you should store the user somewhere where it is forced to be unique. On the other hand, if things would be functionally correct but maybe a bit weird with user values that were out of sync, then pushing it down into the pages — particularly as a non-editable value — is a good way to reduce plumbing.

We use out messages in a way where they subsume commands. Update functions return a list of out messages and one of the standard cases for an out message is “send this command”. The code that would just map commands to add addressing instead maps over the list of out messages coming from the child applying changes to the parent and/or accumulating parent out messages for the next level. It’s more wordy than the normal Elm command architecture but it fits essentially the same pattern which is nice. The general notion is that out messages and commands are the same thing from the child’s perspective: a request for something to happen that is beyond the child’s ability to perform itself.

We used to use out messages for state queries as well — thinking of them as being much like HTTP queries — but this resulted in more convoluted control flow than was ideal with requests going from child to parent and then back to the child. So, we now handle ancestral state either by passing it down to functions like view and subscriptions which have no power to modify state anyway and broadcasting it to descendants when it changes for those cases where children want to respond in their own state to changes in ancestral state. I’m less thrilled about the latter and am looking at ways to eliminate it but the data structures and algorithms often get more complicated in the absence of the ability to react to parental state changes. But that’s its own topic.

Mark

5 Likes