Skip to content

Instantly share code, notes, and snippets.

@jzxhuang
Last active March 28, 2019 13:40
Show Gist options
  • Save jzxhuang/63f0b09fd05d158376d7bdcaace2d0ef to your computer and use it in GitHub Desktop.
Save jzxhuang/63f0b09fd05d158376d7bdcaace2d0ef to your computer and use it in GitHub Desktop.
Full example of sending an HTTP request that returns a detailed Response in Elm using expectStringDetailed
module Main exposing (main)
{-
This example demonstrates how to send an HTTP request and get back
a detailed response using expectStringDetailed. The response will be
more detailed for both successful and unsuccessful requests.
From this post: https://medium.com/@jzxhuang/handling-detailed-http-responses-in-elm-6ddd02322e
-}
import Browser
import Html exposing (Html, button, div, text)
import Html.Attributes exposing (src, width)
import Html.Events exposing (onClick)
import Http
-- Code for a request that returns a detailed response, as seen in the post
type ErrorDetailed
= BadUrl String
| Timeout
| NetworkError
| BadStatus Http.Metadata String
| BadBody String
convertResponseString : Http.Response String -> Result ErrorDetailed ( Http.Metadata, String )
convertResponseString httpResponse =
case httpResponse of
Http.BadUrl_ url ->
Err (BadUrl url)
Http.Timeout_ ->
Err Timeout
Http.NetworkError_ ->
Err NetworkError
Http.BadStatus_ metadata body ->
Err (BadStatus metadata body)
Http.GoodStatus_ metadata body ->
Ok ( metadata, body )
expectStringDetailed : (Result ErrorDetailed ( Http.Metadata, String ) -> msg) -> Http.Expect msg
expectStringDetailed msg =
Http.expectStringResponse msg convertResponseString
-- Send HTTP request using expectStringDetailed
sendDogHttpRequest : Cmd Msg
sendDogHttpRequest =
Http.get
{ url = dogApiUrl ++ "woof"
, expect = expectStringDetailed DogApiResponse
}
-- Code for the application
type Model
= Fetching
| Success ( Http.Metadata, String )
| Error ErrorDetailed
type Msg
= SendRequest
| DogApiResponse (Result ErrorDetailed ( Http.Metadata, String ))
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
SendRequest ->
( model, sendDogHttpRequest )
DogApiResponse httpResponse ->
case httpResponse of
Ok detailedResponse ->
( Success detailedResponse, Cmd.none )
Err detailedError ->
( Error detailedError, Cmd.none )
view : Model -> Browser.Document Msg
view model =
{ title = "Example: Detailed HTTP Responses in Elm"
, body =
[ div []
[ div []
(case model of
Fetching ->
[ text <| "Fetching a random dog pic..." ]
Success ( metadata, body ) ->
[ div [] [ text "Metadata as String:" ]
, div [] [ text <| Debug.toString metadata ]
, div []
[ if String.endsWith ".mp4" body then
Html.video [ src <| dogApiUrl ++ body , width 300] []
else
Html.img [ src <| dogApiUrl ++ body, width 300 ] []
]
]
Error error ->
[ text "Uh oh, there was an error! We can access the metadata and body if the error was \"BadStatus\"" ]
)
, button [ onClick SendRequest ] [ text "Get a random dog!" ]
]
]
}
dogApiUrl =
"https://random.dog/"
main : Program () Model Msg
main =
Browser.document
{ init = \() -> ( Fetching, sendDogHttpRequest )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment