Reputation: 2513
I have an Elm app that needs to communicate to a server using Http
on Elm Platform 0.14.1. The app needs to validate that its requests are valid before sending them to the server.
Currently I am using a function makeRequest
to take some data from the model and make an Http.Request
based on it with invalid requests returning Http.get ""
. This is a hack and I want to replace it with proper error handling.
The types of the functions I have are:
makeRequest : List String -> Request String
Http.send : Signal (Request a) -> Signal (Response String)
I want to wrap the result of makeRequest
in Result
so that I can handle the errors properly. I also want to wrap Http.send
so that it propagate errors.
Ideally I would like to end up with:
newMakeRequest : List String -> Result String (Request String)
newSend : Signal (Result String (Request a)) -> Signal (Result String (Response String))
Constructing newMakeRequest
is trivial. But I am not sure how to approach newSend
or if it is even possible.
Upvotes: 2
Views: 549
Reputation: 5958
Ok, so all you need is the newSend
right? That's possible:
newSend : Result x (Reponse a) -> Signal (Result x (Request a)) -> Signal (Result x (Response a))
newSend defaultResp s =
let reqs =
s |> Signal.keepIf isOk (Ok (Http.get ""))
|> Signal.map unpackOk
errs =
s |> Signal.dropIf isOk defaultResp
|> Signal.map errIdentity
in Signal.merge errs (Signal.map Ok (Http.send reqs))
-- Change the type of an Err Result.
errIdentity : Result x a -> Result x b
errIdentity =
Result.map (Debug.crash "errIdentity: Don't call this function on an Ok!")
unpackOk : Result x a -> a
unpackOk =
case res of
Ok a -> a
Err x -> Debug.crash "unpackOk: Don't call this function on an Err!"
isOk : Result x a -> Bool
isOk res =
case res of
Ok _ -> True
Err _ -> False
I'm not sure if you can get rid of the default response. And I am a bit worried about the ordering of events.. The responses are asynchronous, so you may get Err
s from the input signal on the output signal immediately while an Ok
request is still pending. Not sure how to fix that. Not sure if that's a problem for you either.
Upvotes: 2