marc walter

Decoding models from a JSON formatted string

2018-01-17 (Last updated on 2018-09-01)

A small snippet useful if one Elm program consists of two very different components.

How to use it:

  1. Pass data to the instantiation of the elm program as a String
  2. Try different decoders on the data (Json.Decode.oneOf)
  3. Display the SPA that can handle the data or an error page

If this iframe is not displayed, try opening the file directly.

This example is a little simpler, but it works in elm-reactor like that.

Download the code, or download the code for Elm 0.18

type Model
    = Spa1 State1
    | Spa2 State2
    | Error String


type alias State1 =
    { one : String }


type alias State2 =
    { one : String, two : Int }


decode : String -> Model
decode str =
    case
        Json.Decode.decodeString modelDecoder str
    of
        Ok (Spa1 data) ->
            let
                _ =
                    Debug.log "result" data
            in
            Spa1 data

        Ok (Spa2 data) ->
            Spa2 data

        Ok (Error err) ->
            Error err

        Err err ->
            let
                _ =
                    Debug.log "Could not decode" err
            in
            Error <| Json.Decode.errorToString err


modelDecoder : Json.Decode.Decoder Model
modelDecoder =
    Json.Decode.oneOf
        [ Json.Decode.map Spa2 state2Decoder
        , Json.Decode.map Spa1 state1Decoder
        ]


state1Decoder : Json.Decode.Decoder State1
state1Decoder =
    Json.Decode.map State1
        (Json.Decode.field "one" Json.Decode.string)


state2Decoder : Json.Decode.Decoder State2
state2Decoder =
    Json.Decode.map2 State2
        (Json.Decode.field "one" Json.Decode.string)
        (Json.Decode.field "two" Json.Decode.int)