elmelm-architecture

Elm - Turn Msg into Cmd Msg


I'm trying to modify a simple app from the elm-lang tutorial to first update the model, then trigger another update.

update msg model =
  case msg of
    MorePlease ->
      (model, getRandomGif model.topic)

    NewGif (Ok newUrl) ->
      ( { model | gifUrl = newUrl }, Cmd.none)

    NewGif (Err _) ->
      (model, Cmd.none)

    -- my addition
    NewTopic newTopic ->
      ({ model | topic = newTopic}, MorePlease)

This fails in the compiler because the NewTopic branch:

The 3rd branch has this type:

( { gifUrl : String, topic : String }, Cmd Msg )

But the 4th is:

( { gifUrl : String, topic : String }, Msg )

So my Msg needs to be type Cmd Msg. How can I turn" my Msg into a Cmd Msg?

note: I recognize there is a simpler way to make this change, but I'm trying to understand Elm more fundamentally


Solution

  • There is really no need to turn Msg into a Cmd Msg. Remember that update is just a function, so you can call it recursively.

    Your NewTopic case handler can be simplified to this:

    NewTopic newTopic ->
        update MorePlease { model | topic = newTopic}
    

    If you really truly wanted the Elm Architecture to fire off a Cmd for this scenario, you could do a simple map of Cmd.none to your desired Msg:

    NewTopic newTopic ->
        ({ model | topic = newTopic}, Cmd.map (always MorePlease) Cmd.none)
    

    (not actually recommended)