I do rather like #2 - it seems to me that you could even have the result of 
update be either the usual model/command pair *or* a UserId, i.e. replace 
both return values, not just the second one. Something like:

type State
    = Active ( Model, Cmd Msg )
    | Finished UserId

update : Msg -> Model -> State
update msg model =
    ...

which is very explicit - either we're still in the process of logging in, 
so here is the updated model and some more commands to perform, or the user 
has finished logged in so you should use the returned user ID to switch to 
some new state.

On Tuesday, 9 August 2016 10:12:26 UTC+10, Mark Hamburg wrote:
>
> Here is the case I'm looking at: My SPA can be in one of three state — 
> probably more before I'm done but three will be sufficient for this 
> discussion — logging in, active, and logged out. So, here's my model:
>
> type Model
>   = LoggingIn LoggingIn.Model
>   | Active Active.Model
>   | LoggedOut LoggedOut.Model
>
> The message handling has appropriate tag messages and the update function 
> looks fairly nice by casing on (msg, model). All good so far.
>
> Now, for the question: How best to drive state transitions?
>
> For example, when we finish logging in, we should get back a UserId that 
> we can hand to Active.init to get an (Active.Model, Cmd Active.Msg). How 
> should this be reported? The cases I've considered include:
>
> 1. Add an extra Maybe UserId result to LoggingIn.update.
>
> 2. Replace the second result from LoggingIn.update with something that 
> can be either a Cmd LoggingIn.Msg or a LoggedIn UserId.
>
> 3. Add a loggedInUser : Model -> Maybe UserId function to the LoggingIn 
> module and test this after doing the update.
>
> Interesting side question: If we do succeed in logging in, is it ever 
> reasonable to be returning commands (effects) from that update to the 
> logging in model? The results aren't going to get routed back because that 
> model state is going away. On the other hand, if we were just sending off 
> some sort of external effect for which the result didn't matter, then maybe 
> this could come up.
>
> If the answer to the side question says "yes, it is reasonable to send off 
> commands as part of login success", then the second option needs a more 
> complicated type since we can return both a command AND a user id. In that 
> case, the first case probably wins.
>
> On the other hand, returning triples with what in the general case will be 
> arbitrary third parameters feels like the sort of coding pattern that 
> decays into returning quads and quints.
>
> The benefit of the third path is that now one could imagine testing the 
> logging in module by itself with a view case for when logged in. The state 
> machine just drives us from this state to the active state.
>
> The downside to the third path is that now every state implementation 
> needs to include a state for while it is doing what it would ordinarily do 
> and a state for when it is time to move on and that's more plumbing at 
> those levels. For example, the Active module would similarly gain an 
> isLoggedOut 
> : Model -> Bool function and the model within the module would need to 
> handle the logged out case even though it really has nothing to do in that 
> case,
>
> How would more experienced Elm coders handle this? Is there a sense for 
> best practice?
>
> My personal inclination is probably to go for the first option even though 
> it starts to step out onto the slippery slope. I like the second approach 
> because it feels more rigorous but I think that extra rigor just turns into 
> extra code in practice. My first implementation today pursued the third 
> course and I thought it looked nice in my top-level module until I thought 
> about the fact that it would turn everything below it into a state machine 
> as well.
>
> Mark
>
>

-- 
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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to