004: JSON Decoders

April 27, 2020 0:57:40 55.57 MB Downloads: 0

Basics

Ports and Flags

Here's an Ellie example that shows the error when you have an implicit type that your flags decode to and it's incorrect.

Sorry Dillon... Jeroen won the trivia challenge this time 😉 It turns out that ports will throw exceptions when they are given a bad value from JavaScript, but it doesn't bring down your Elm app. Elm continues to run with an unhandled exception. Here's an Ellie example.

Flags and ports will never throw a runtime exception in your Elm app if you always use Json.Decode.Values and Json.Encode.Values for them and handle unexpected cases. Flags and ports are the one place that Elm lets you make unsafe assumptions about JSON data.

Benefits of Elm's Approach to JSON

  • Bad data won't end up deep in your application logic where it's hard to debug (and discover in the first place)
  • Decouples serialization format from your Elm data types
  • You can do data transformations locally as you build up your decoder, rather than passing your giant data structure through a single transform function

Decoding Into Ideal Types

Note about Decode.maybe. It can be unsafe to use this function because it can cover up failures. Json.Decode.maybe will cover up some cases that you may not have intended to. For example, if an API returns a float we would suddenly get Nothing back, but we probably want a decoding failure here:

import Json.Decode as Decode

""" {"temperatureInF": 86} """ |> Decode.decodeString (Decode.maybe (Decode.field "temperatureInF" Decode.int))
--> Ok (Just 86)

""" {"temperatureInF": 86.14} """ |> Decode.decodeString (Decode.maybe (Decode.field "temperatureInF" Decode.int))
--> Ok Nothing

Json.Decode.Extra.optionalNullableField might have more intuitive and desirable behavior for these cases.

Thank you to lydell for the tip! See the discussion in this discourse thread.

Learning resource

Joël Quenneville’s Blog Posts About JSON Decoders

Guaranteeing that json is valid before runtime

Autogenerating json decoders

Organizing your decoders

Getting Started

  • Understand Json.Decode.map
  • Understand record type aliases - the function that comes from defining type alias Album = { ... }

Submit your question to Elm Radio!