Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 474
steel Avatar asked Mar 09 '17 18:03

steel


2 Answers

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)

like image 189
Chad Gilbert Avatar answered Nov 13 '22 11:11

Chad Gilbert


Add the following function:

run : msg -> Cmd msg
run m =
    Task.perform (always m) (Task.succeed ())

Your code would then turn into:

NewTopic newTopic ->
      ({ model | topic = newTopic}, run MorePlease)
like image 13
Deimos Avatar answered Nov 13 '22 12:11

Deimos