This is an interesting question and important for larger apps.
In the instance I am working on I plan to use a cache, and have implemented
the idea in one of the components so far. I have the relevant top level
component monitor for events in sub-components triggering messages that
require the cache to be supplemented, handling the downloading, and then
routing the result to the cache. I pass the cache down through my view
functions alongside the relevant section of the overall model, and the view
function shows a holding statement for as long as the cache cannot provide
content.
Simon
On Tuesday, 31 May 2016 18:29:44 UTC+2, James Wilson wrote:
>
> In Elm, each component basically has its own internal state (which is
> actually all just a slice of one global model). In my app, I also want
> global state that is independant of any components; for example a
> clientside cache of various API responses (asset details - there could be
> many thousands, user authentication status).
>
> I want any component to be able to call methods that make use of this
> global state. For example, a method to obtain details for items in the
> current view might first look at the global state to see if these items are
> cached. If they arent, the call would provide a Cmd to be issued that gets
> the items (and puts them in the cache), while simultaneously updating the
> state to indicate that they are being loaded (so that the same request
> again from another component doesnt trigger another call to the backend).
> If they are cached, they can be easily returned from there. A first shot at
> a signature might look something like:
>
> getItem : GlobalState -> ID -> Tag -> (GlobalState, Cmd msg)
>
>
>
> However we could partially apply functions that exist on some globalState
> instantiation to hdie the initial state being passed in and end up with:
>
> state.items.getItem : ID -> Tag -> (GlobalState, Cmd msg)
>
>
>
> The downside of this approach is that I have to thread this state through
> multiple calls that might make use of it, and thread it back up explicitly
> through the update functions to get it back to the top. At the top we'd
> then have something like (excuse any mistakes!):
>
> update msg model = case msg of
> SubMsg m ->
> let (newSubModel, subCmds, newGlobalState) = SubComponent.update m
> model.subModel
> in ({ model | state = newGlobalState, subModel = newSubModel}, Sub.map
> SubMsg subCmds)
> ...
>
>
> An alternative approach is to hold this global state in an effect manager,
> and so in the app you'd end up using the Cmd/Sub mechanism to ask for
> things from the state and internally initiate API requests to update the
> state as necessary. We'd end up with an API more like:
>
> getItem : ID -> Tag -> Cmd msg
>
>
> or
>
> state.items.getItem : ID -> Tag -> Cmd msg
>
>
> where the returned Cmd would either lead to an item being sent to the
> component immediately via a cache (where Tag is a Msg type the component
> knows about) or after it was obtained via some backend. This would make all
> retrieving of state async but seems to simplify the interface (perhaps at
> the cost of more complexity in implementing the effect manager).
>
> Which approach do people think is best for working with global state
> (neither is an option if you have a better way!)? Do you get away with not
> needing this kind of thing (and if so, how)? I'd love to hear back,
> especially from those that have had experience building larger apps in Elm!
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.