The point is to avoid using Cmd.map
, right?
What we want is Api.elm
knows how to get a Thing
from a server, but doesn’t want to deal with what to do with the response.
And Main.elm
, and other clients of Api.elm
, want to get a Thing
from a remote server so they can do awesome things with it, but they don’t want to deal with how to get it.
So Api.elm
can be lazy about doing things with Things
:
module Api exposing (getSomething)
{-| I'll get a Thing for you, just tell me what you want done with it.
For example, I could put it into some kind of msg for you, then I'll give
you a Cmd you can invoke to get *that kind of msg* eventually.
-}
getThing : (Result Http.Error Thing -> msg) -> Cmd msg
getThing constructor =
Http.request
{ method : "GET"
, headers : []
, url : "http://thingServer.someplace.com/"
, body : Http.emptyBody
, expect : Http.expectJson constructor thingDecoder
, timeout : Nothing
, tracker : Nothing
}
And Main.elm
is lazy about how to get things:
{-| When I init, the Api is going to do some work for me, and then
I'll get a GotThing message that hopefully has a Thing in it!
-}
main : Program () MyAwesomeModel MyMainMessageType
main =
Browser.element
{ init : () -> ( init, Api.getThing GotThing )
, view : view
, update : update
, subscriptions : always Sub.none
}
type MyMainMessageType
= GotThing (Result Http.Error Thing)
update :
MyMainMessageType
-> MyAwesomeModel
-> ( MyAwesomeModel, Cmd MyMainMessageType )
update msg model =
case msg of
GotThing (Ok thing) ->
Thing.doAllTheThings thing
GotThing (Err error) ->
dealWith error
When they said suggested passing ( a -> msg)
, that translated to my example as passing the type constructor GotThing
in Api.getThing GotThing
. Note that GotThing
by itself has the type ( Result Http.Error Thing -> MyMainMessageType)
, in other words its a constructor for values of MyMainMessageType
. And that Api.getThing
takes as its first argument a ( Result Http.Error Thing -> msg)
, or in other words, it just wants a message constructor for some type of msg
so that it can cram the Thing
it gets somewhere. It returns a Cmd
that could produce that type of msg
eventually.