Shared State among multiple submodules

Shared State

In Elm, splitting up a module into multiple smaller modules may be cumbersome and result in issues relating to the single source of truth principle. That’s why, in real world Elm applications, it is not seldom to encounter very large modules. This article will introduce an architectural concept to deal with this issue by allowing the division of modules into logical , consistent and reusable submodules.

Blog Post: curry-software.com/en/blog/elm_shared_state
Follow the code of this example on github.com/CurrySoftware/elm-shared-state-example.

4 Likes

This is great, very clean way to update shared state.

1 Like

BTW, I have one question: how do you handle pages where a shared argument is required?

I.e. the logged in user is optional, and I’m assuming you handle this as share state. So we have Maybe User.

For a few pages the logged in user is optional, which is then fine, but for most pages we need to have it. Handling that all the time as a maybe is annoying. So you can pass that in as argument to Page but then we have user at two places and in case you want to update it, you could have to update it in two places.

How do you suggest you handle cases like this? User is obviously one example, I have quite a few examples where I have details which get collected along the way, and do not need to be refreshed every time. And for those pages these details are required, but until I have them they are a maybe.

2 Likes

That’s a good question.
We have a similar problem in our codebase but we solve it with Maybe.map and whenJust.
But in your case, as the whole page would not need to be rendered/updated if the User was not present I would propose the following solution:

assumeUserUpdate : Msg -> Maybe User -> (Msg -> User -> User) -> User
assumeUserUpdate msg user update =
   case user of
      Just u ->
              update msg u

      Nothing ->
             user -- that would be a 401

Of course, you can replace Maybe User and User by SharedState and LoggedInState or something similar to handle it in a more general way.
This can than be used for all pages that need a user.

The same could be done for views.

Let me know if this helps. Maybe we can look at your problem together and find a specific solution for your usecase.

Where is this function defined? Is that from stylish-elephants?

You may use this search page to find out such information. According to the search results, it is from style-elements.

1 Like

I saw it first in style-elements, but you can define it yourself for Html as well:

whenJust: Maybe a -> (a -> Html msg) -> Html msg
whenJust maybe view =
  case maybe of
        Just val ->
            view val

        Nothing ->
            text ""

In view functions you can than use it like this:

  div [] [
    whenJust user (\u -> text u.name)
  ]

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.