Decoding JSON HTTP Responses

We’ve already seen how we can use Http.expectString to obtain a String from a server, and how we can use decodeString and a Decoder to translate a String into a list of Photo records for our Model.

Although we could use Http.expectString and decodeString to populate our Model in this way, there is another function in the Http module which will take care of both for us.

# Http.expectJson

The Http.expectJson function requests data from a server and then decodes it. Here is how the types of Http.expectString and Http.expectJson match up:

expectString : (Result Http.Error String -> msg) -> Expect msg

expectJson : (Result Http.Error val -> msg) -> Decoder val -> Expect msg

Comparing types like this suggests how these functions are similar and how they differ. They both accept a function to translate a Result into a msg. Both Result types have Http.Error as its Err type. However, where expectString takes no other arguments and always produces a String for its Result’s Ok type, getJson additionally accepts a Decoder val, and on success produces an Ok val result instead of Ok String.

As you might expect, if we give Http.expectJson a decoder of (list int) and the response it gets back is the JSON payload "[1, 2, 3]", then Http.get will successfully decode that into Ok (List Int). If decoding fails, we will instead get Err BadBody.

# The BadBody Error

What’s BadBody? It’s a variant of that Http.Error type […] Http.Error is a custom type that describes various ways an HTTP request can fail. It looks like this:

type Error = BadUrl String | Timeout | NetworkError | BadStatus Int | BadBody String

The BadBody variant occurs when the body of the HTTP response failed to decode properly. Because Error is a custom type, we can run a case-expression on any Http.Error value — with different branches for Timeout, NetworkError, and so on — to do custom error handling based on what went wrong.

Tip: The lower-level Http.request function lets you customize requests in greater depth than Http.get does.

[…]

~

FELDMAN, Richard, 2020. Elm in action. Shelter Island, NY: Manning. ISBN 978-1-61729-404-4, p.117–119