Skip to content

Instantly share code, notes, and snippets.

@ccapndave
Created December 1, 2016 15:08
Show Gist options
  • Save ccapndave/83f18a071d88759a819a974b40efe8bf to your computer and use it in GitHub Desktop.
Save ccapndave/83f18a071d88759a819a974b40efe8bf to your computer and use it in GitHub Desktop.
module HttpReader exposing
( ResponseReader
, jsonReader
, get
, withZeroStatusAllowed
)
{-|
-}
import Json.Decode as JD exposing (Decoder)
import Task exposing (Task)
import Http exposing (Error)
{-| A ResponseReader is a function that transforms an Http.Response into a Result. This can be used to perform any transformation
on the data returned from an Http request.
-}
type alias ResponseReader a =
Http.Response String -> Result String a
{-| This is a helper function to turn a Json Decoder into a ResponseReader which decodes Json with the given Decoder.
-}
jsonReader : Decoder a -> ResponseReader a
jsonReader decoder =
\response ->
response.body
|> JD.decodeString decoder
{-| Equivalent to Http.get, but taking a ResponseReader instead of a Decoder.
-}
get : String -> ResponseReader a -> Http.Request a
get url responseReader =
Http.request
{ method = "GET"
, headers = []
, url = url
, body = Http.emptyBody
, expect = Http.expectStringResponse responseReader
, timeout = Nothing
, withCredentials = False
}
{-| This allows an Http task to still succeed even if the HTTP status code is 0 (as happens when retrieving data from a service worker,
or from a file:/// URL as often occurs when running under wrappers like Cordova or Electron). Its argument is the same reader that was
given to the initial request.
get "file.json" (jsonReader decoder)
|> Http.toTask
|> withZeroStatusAllowed (jsonReader decoder)
-}
withZeroStatusAllowed : ResponseReader a -> Task Http.Error a -> Task Http.Error a
withZeroStatusAllowed responseReader task =
task
|> Task.onError (\err ->
case err of
Http.BadStatus response ->
if response.status.code == 0 then
response
|> responseReader
|> (\result ->
case result of
Ok value ->
Task.succeed value
Err decodeErrStr ->
Task.fail <| Http.BadPayload decodeErrStr response
)
else
Task.fail err
otherwise ->
Task.fail err
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment