On Thursday, October 13, 2016 at 2:17:50 AM UTC+1, Fa Qing wrote:
>
> The PageLevel is calling the service level for a command. We want
> intermediate effects, before the final command. But we don't want to just
> issue intermediate commands either, because the state that is reacting to
> the final command (the only one we have currently) could also be affected
> by the intermediate command. Also, it doesn't help us refactor out the
> (common) inputs into the service layer, such as a header value we need to
> write out.
>
> It seems like there's a missing abstraction from the Elm architecture.
>
Hi,
I decided to make an Auth module a special case, and not use the nested TEA
architecture for it.
I have an API like this for Auth:
port module Auth exposing (..)
type alias Credentials =
{ username : String
, password : String
}
login : Credentials -> Cmd msg
login authRequest =
sendLogin authRequest
logout : Cmd msg
logout =
sendLogout ()
unauthed : Cmd msg
unauthed =
sendUnauthed ()
port sendLogin : Credentials -> Cmd msg
port sendLogout : () -> Cmd msg
port sendUnauthed : () -> Cmd msg
The ports I can use from anywhere in the application to login, logout or on
a 403 unauthorized to set the global state to not logged in (unauthed).
The token is part of the state of the Auth module, which is linked in to
the global state of the Main module of the application. All Msgs to
sub-modules go through the update method of the Main module, and use the
nested TEA and the 'lift' function from Material.Helpers to forwad them on
the appropriate child module. Like this:
AccountsMsg a ->
lift .accounts (\m x -> { m | accounts = x }) AccountsMsg
Accounts.State.update a model
Passes events for the Accounts module on to it.
This could easily be adapted to pass along the current Auth token.
Another way, perhaps more convenient, could be to hold the Auth token in
'session storage' (not local storage as that would be insecure), and
provide a global port in the Auth module to obtain it.
As Peter suggests, make all your API call functions take the token as an
extra arg.
I didn't need that as I opted to use cookies, which means the browser does
it for me. However, at some point I will need to deal with APIs that insist
on tokens in the header. I think treating auth as a bit of a special case
and using some ports to make it more easily global across the application
feels right to me. It is not necessary though, there are other ways of
doing 'out messages' whereby a child module sends a message to another
child module without resorting to using ports.
--
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.