I am trying to learn Elm, and have been trying to work out the best way to architect a scaleable application. Regarding routing, I want to have some simple logic rendering the various views depending on the current route
, emphasis on simple logic. However, inside some of my views, I want to change the route depending on the model. For example, in my Players
view, I only want to render it if I have received some data from the server. If the request is pending or failed, I would like to display an error page. I realize I could perform this logic inside the Players
view, but I would prefer to dispatch a message to the model to change the route to a different view. I only know how to dispatch messages from events (onClick
, etc...). Is this possible or am I working outside the designs of the language?
This is my current setup, but I would like to change
Nothing ->
notFoundView
To dispatch a message that changes the route
Core View
view : Model -> Html Msg
view model =
div []
[ page model
]
page : Model -> Html Msg
page model =
case model.route of
PlayersRoute ->
listView model.playersModel.players
PlayerRoute id ->
editView model id
NotFoundRoute ->
notFoundView
Players View
editView : Model -> PlayerId -> Html Msg
editView model id =
case model.playersModel.players of
NotAsked ->
text ""
Loading ->
text "Loading ..."
Failure err ->
text (toString err)
Success players ->
let
maybePlayer =
players
|> List.filter(\player -> player.id == id)
|> List.head
in
case maybePlayer of
Just player ->
core player
Nothing ->
notFoundView
Thank you in advance for any help!
It is possible to match on contents of sub models and see if it is an error route, before passing the message down to the edit view. So, the core page
function would look like this.
page : Model -> Html Msg
page model =
case model.route of
PlayersRoute ->
listView model.playersModel.players
PlayerRoute id ->
case model.playersModel.players of
Failure err ->
errorView err
_ ->
editView model id
NotFoundRoute ->
notFoundView
Another option would be using full routes, and use the Navigation package. But, that would involve the overhead of setting up routes for each page. You would be able to send a Cmd to change the page at the top level of the app. Changing the Url would then cause a completely different page to be rendered.