There is a quick guideline to follow if you want to use this module:
Add a type alias. For example:
type alias UserAction =
Action
Never --Allow Updates?
Never --Allow Cmd other then Cmd.none?
Never --Allow Transitions?
Never --Allow Exit?
Start by setting the first Never
to your stateModel
:
type alias UserAction =
Action
UserModel -- updates allowed.
Never --Allow Cmd other then Cmd.none?
Never --Allow Transitions?
Never --Allow Exit?
If you want to allow Cmd, change the second Never to your stateMsg
. In our
example, this would be UserMsg
.
Write your update function. In our very basic example, it looks like this:
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
(UserSpecific userMsg,User userModel) ->
updateUser userMsg userModel
|> Action.config
|> Action.withUpdate User never
-- If you want to allow Cmd you would use
-- the following line
--|> Action.withUpdate User UserSpecific
|> Action.apply
_ ->
(model,Cmd.none)
If needed, go back to Step 2 and replace another Never
.
An Action
specifies the behaviour of an update function.
An Action
can either be
Update (model,Cmd msg)
- Updates the model as usual.Transition transitionData
- Transitions to a different model using data
(like logging in)Exit
- Transitions to a different model with less access (like logging out)An Action
has 4 type parameters: model
,msg
,transitionData
and exitAllowed
.
exitAllowed
should be set to ()
. However,Exit
, then set exitAllowed
to Never
.Update (model,Cmd msg)
, then set model
to Never
.Cmd msg
other then Cmd.none
, then set msg
to Never
.Transition transitionData
, then set transitionData
to Never
.updating : ( stateModel, Platform.Cmd.Cmd stateMsg ) -> Action stateModel stateMsg transitionData exitAllowed
Updates the model as usual.
import Task
updating (42, Cmd.none)
|> Action.config
|> Action.withUpdate (\int -> (int,0)) never
|> Action.apply
|> Tuple.first
--> (42,0)
Checklist in case of errors:
stateModel
should not be Never
withUpdate
transitioning : transitionData -> Action stateModel stateMsg transitionData exitAllowed
Transitions to a different model.
import Task
transitioning 42
|> Action.config
|> Action.withTransition (\int -> ((int,0),Cmd.none)) Just never
|> Action.apply
|> Tuple.first
--> Just (42,0)
Checklist in case of errors:
transitionData
should not be Never
withTransition
exiting : Action stateModel stateMsg transitionData ()
Transitions to a different model with less access. (like logging out)
import Task
exiting
|> Action.config
|> Action.withExit ((42,0),Cmd.none)
|> Action.apply
|> Tuple.first
--> (42,0)
Checklist in case of errors:
exitAllowed
should be ()
withExit
config : Action stateModel stateMsg transitionData exitAllowed -> ActionConfig stateModel stateMsg transitionData exitAllowed (Config (Basics.Never -> ( model, Platform.Cmd.Cmd msg )) (Basics.Never -> model) (Basics.Never -> msg) (Basics.Never -> ( model, Platform.Cmd.Cmd msg )))
Starts the configuration of the Action.
The most basic config pipeline looks like this:
updateFunction
|> Action.config
|> Action.apply
with updateFunction : Model -> Msg -> Action Model Msg TransitionData ExitAllowed
.
You will need to add withExit
,withUpdate
and or withTransition
to make
the code compile.
apply : ActionConfig stateModel stateMsg transitionData exitAllowed { exitFun : exitAllowed -> ( model, Platform.Cmd.Cmd msg ), modelMapper : stateModel -> model, msgMapper : stateMsg -> msg, transitionFun : transitionData -> ( model, Platform.Cmd.Cmd msg ) } -> ( model, Platform.Cmd.Cmd msg )
Ends the Configuration and returns a (Model, Cmd Msg)
.
withUpdate : (stateModel -> model) -> (stateMsg -> msg) -> ActionConfig stateModel2 stateMsg transitionData exitAllowed (Config a b c d) -> ActionConfig stateModel2 stateMsg transitionData exitAllowed (Config a (stateModel -> model) (stateMsg -> msg) d)
Specifies how the stateModel
/stateMsg
is embedded in the main model
/msg
.
Lets say we have a password protected area:
type Model
= Maybe RestrictedModel
type Msg
= GuestSpecific GuestMsg
| RestrictedSpecific RestrictedMsg
Then we would use withUpdate Just RestrictedSpecific
for the restricted area and
withUpdate (always Nothing) GuestSpecific
for the guest area.
Checklist in case of errors:
stateModel
should not be Never
withUpdate
withTransition : (transitionData -> ( stateModel2, Platform.Cmd.Cmd stateMsg2 )) -> (stateModel2 -> model) -> (stateMsg2 -> msg) -> ActionConfig stateModel stateMsg transitionData2 exitAllowed (Config a b c d) -> ActionConfig stateModel stateMsg transitionData2 exitAllowed (Config a b c (transitionData -> ( model, Platform.Cmd.Cmd msg )))
Specifies how the state transitions to another state.
Lets say we want a user to login.
type alias User =
{ name : String
, admin : Bool
}
initUser : String -> User
initUser string =
{ name = string
, admin = string == "Admin"
}
type Model
= Maybe User
Then we can use withTransition \string -> ( initUser string, Cmd.none) Just never
for logging in a user.
Checklist in case of errors:
transitionData
should not be Never
withTransition
withCustomTransition : (transitionData -> ( model, Platform.Cmd.Cmd msg )) -> ActionConfig stateModel stateMsg transitionData2 exitAllowed (Config a b c d) -> ActionConfig stateModel stateMsg transitionData2 exitAllowed (Config a b c (transitionData -> ( model, Platform.Cmd.Cmd msg )))
Specifies a Transition to multiple possible states.
Checklist in case of errors:
transitionData
should not be Never
withTransition
withExit : ( model, Platform.Cmd.Cmd msg ) -> ActionConfig stateModel stateMsg transitionData () (Config (Basics.Never -> ( model, Platform.Cmd.Cmd msg )) b c d) -> ActionConfig stateModel stateMsg transitionData () (Config (() -> ( model, Platform.Cmd.Cmd msg )) b c d)
Specifies the state the resulting (model, Cmd msg)
when exiting.
For a hard exit you can use
withExit (init ())
Checklist in case of errors:
exitAllowed
should be ()
withExit