# JSON decoding when fields can be different

**URL:** <https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602>\
**Category:** Learn\
**Created:** [November 3, 2019, 8:43pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602 "2019-11-03T20:43:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![curiouslearn](https://avatars.discourse-cdn.com/v4/letter/c/f05b48/32.png) [@curiouslearn](https://discourse.elm-lang.org/u/curiouslearn)\
**Post date:** [November 3, 2019, 8:43pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/1 "2019-11-03T20:43:01Z")

</div>

I would appreciate some pointers on how to tackle the following.  
I am using websockets to send some data from server to the client. I receive the message in Javascript (through the onmessage handler of the websocket connection), which I forward to Elm through a port. Everything is easy when this message has fixed fields. However, what is the recommended way to handle this if there can be different types of messages. Following are two examples (I am writing the JSON message):

```
{eventtype: "a",
 eventdata: {f1a: "v1", f2a: "v2", f3a: someobject}

```

}

```
{eventtype: "b",
 eventdata: {f1b: "v1", f2b: someint}

```

}

One way I can think of is setup different ports for each kind of message and different message handlers for each type of message. Then, when the message comes from the server, I inspect the message in Javascript, and use the port and message handler based on the result of that inspection.

Is there a better way than this, or is this the recommended way?

Thank you.

---

<div class="post-metadata">

**Author:** ![malaire](https://avatars.discourse-cdn.com/v4/letter/m/b782af/32.png) [@malaire](https://discourse.elm-lang.org/u/malaire)\
**Post date:** [November 3, 2019, 8:58pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/2 "2019-11-03T20:58:10Z")

</div>

You can create a single decoder which can handle different messages.

For example you can use `andThen` to create branching decoder like this:

```auto
import Json.Decode as JD

type DecodedType
    = TypeA String String SomeObject
    | TypeB String Int

decoder =
    JD.field "eventtype" JD.string
        |> JD.andThen
            (\eventtype ->
                case eventtype of
                    "a" ->
                        JD.map3 TypeA
                            (JD.field "f1a" JD.string)
                            (JD.field "f2a" JD.string)
                            (JD.field "f3a" someObjectDecoder)
                    "b" ->
                        JD.map2 TypeB
                            (JD.field "f1b" JD.string)
                            (JD.field "f2b" JD.int)
                    other ->
                        JD.fail <| "Unknown eventtype: " ++ other
            )

```

---

<div class="post-metadata">

**Author:** ![curiouslearn](https://avatars.discourse-cdn.com/v4/letter/c/f05b48/32.png) [@curiouslearn](https://discourse.elm-lang.org/u/curiouslearn)\
**Post date:** [November 3, 2019, 11:05pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/3 "2019-11-03T23:05:16Z")

</div>

Thank you very much for the example. I will try this and report back. I want to reiterate that the example makes it much easier to follow your solution.

---

<div class="post-metadata">

**Author:** ![curiouslearn](https://avatars.discourse-cdn.com/v4/letter/c/f05b48/32.png) [@curiouslearn](https://discourse.elm-lang.org/u/curiouslearn)\
**Post date:** [November 4, 2019, 2:21am UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/4 "2019-11-04T02:21:40Z")

</div>

Just wanted to say that this worked great! Thank you for your help.

---

<div class="post-metadata">

**Author:** ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)\
**Post date:** [November 4, 2019, 4:00pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/5 "2019-11-04T16:00:03Z")

</div>

@curiouslearn, if you want to dig a bit deeper into the world of conditionally decoding into different structures, you may find this article helpful 🙂

> **[5 Common JSON Decoders](https://thoughtbot.com/blog/5-common-json-decoders)**
>
> Elm JSON decoding in 5 common scenarios

---

<div class="post-metadata">

**Author:** ![curiouslearn](https://avatars.discourse-cdn.com/v4/letter/c/f05b48/32.png) [@curiouslearn](https://discourse.elm-lang.org/u/curiouslearn)\
**Post date:** [November 4, 2019, 7:21pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/6 "2019-11-04T19:21:40Z")

</div>

@joelq, thanks very much for the link. Look forward to reading that article.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [November 14, 2019, 7:21pm UTC](https://discourse.elm-lang.org/t/json-decoding-when-fields-can-be-different/4602/7 "2019-11-14T19:21:45Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
