Here is a quick example sketch of wrapping Http calls in request objects
and delaying conversion to commands. Untested but it compiles. (The tricky
part was handling the decoder since we need to bury the decoded type.)
type alias HttpResult a =
Result Http.Error a
makeStringTagger : Json.Decode.Decoder a -> (HttpResult a -> msg) ->
(HttpResult String -> msg)
makeStringTagger decoder tagger =
let
stringDecoder =
Json.Decode.decodeString decoder
>> Result.formatError Http.UnexpectedPayload
in
\result -> Result.andThen result stringDecoder |> tagger
type Request msg
= Get String (HttpResult String -> msg)
| Command (Cmd msg)
| Batch (List (Request msg))
get : (Result Http.Error a -> msg) -> String -> Json.Decode.Decoder a ->
Request msg
get tagger url decoder =
Get url (makeStringTagger decoder tagger)
command : Cmd msg -> Request msg
command =
Command
batch : List (Request msg) -> Request msg
batch =
Batch
-- We need mapping support for Requests just like Cmds.
map : (a -> b) -> Request a -> Request b
map fn request =
case request of
Get url tagger ->
Get url (tagger >> fn)
Command cmd ->
Command <| Cmd.map fn cmd
Batch list ->
Batch <| List.map (map fn) list
-- At the service layer, we need to map back out to Cmds
toCmd : Request msg -> Cmd msg
toCmd request =
case request of
Get url tagger ->
Http.getString url
|> Task.toResult
|> Task.map tagger
|> Task.perform (Debug.crash "never fail") identity
Command cmd ->
cmd
Batch list ->
Cmd.batch <| List.map toCmd list
Mark
On Fri, Oct 14, 2016 at 4:17 PM, Mark Hamburg <[email protected]> wrote:
> I think the requests-as-an-alternative-to-commands pattern would serve
> you here. (Sorry no link but there was a more detailed example a while
> back.)
>
> Basically, you create a type that parallels Cmd in that it supports batch
> and map functionality and you have it embody the notion of making HTTP
> requests. When the requests get to your service layer, they get turned into
> actual HTTP Cmds with the appropriate auth token attached. (Your request
> type should also allow wrapping normal Cmds so that you can pass those
> through as well.)
>
> This pattern essentially handles "middleware" as an outer wrapper on the
> model standing between your "real" model and the outside world.
>
> Mark
>
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.