The updating of the cache sounds to me like this: 1. if we have the info in cache, just supply the info without a HTTP GET 2. if we don't have the info in cache, return a different Msg that encapsulates the msg that requested the original information and the info required for the cache update.
Here is a quick update of the code I've previously posted to include this caching mechanism. https://gist.github.com/pdamoc/d492ab58023926cd4d4950f12e5e170d On Tue, May 31, 2016 at 10:05 PM, James Wilson <[email protected]> wrote: > The key part that's not coded in the gist is the use of a cache/global > state object, however I think I see what you're getting at - pass back up > the chain a Req object, say, and at the top we can turn it into a Cmd > using, say, some top level global state as well as whatever other data we > need. This may lead to a request being made to the server or it may not. > > The other part of the puzzle is actually updating the cache when a request > is made. Req.toCmd for instance could return an updated GlobalState so that > it's able to cache "pending" states on values (so that we can avoid > duplicating requests). To update the cache when the response actually comes > in we could have toCmd return a Cmd.batch of 2 commands, one that will > fail/succeed and send a message to the component that initiated the Req, > and one that will send a message aimed at the top level cache itself. > > Thanks Peter, I'll definitely mull over this! > > On Tuesday, 31 May 2016 19:45:42 UTC+1, Peter Damoc wrote: >> >> ADT in Elm is one of its most powerful weapons. >> >> You could encapsulate your requests in a type and use this type at top >> level to fulfill them. >> >> For example: instead of returning Cmd msg you return some Req msg that >> can be turned into a Cmd msg at top level based on some context >> information. >> >> Here is a gist with a skeleton of how I view this implemented: >> https://gist.github.com/pdamoc/a47090e69b75433efa60fe4f70e6a06a >> >> I've sent the base of the URL as a simple String in `Req.toCmd` but you >> can imagine a more complex type holding all kind of information (e.g. >> cache, auth, etc ) . >> Also, I've kept the type of the Req simple (only saved the rest of the >> URL based on the user and the request) but one could use it to store all >> the info needed when you will turn the Req into a Cmd. >> >> >> >> >> >> >> On Tue, May 31, 2016 at 7:29 PM, James Wilson <[email protected]> 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. >>> >> >> >> >> -- >> There is NO FATE, we are the creators. >> blog: http://damoc.ro/ >> > -- > 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. > -- There is NO FATE, we are the creators. blog: http://damoc.ro/ -- 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.
