JSON decoding when fields can be different

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.

1 Like

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

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

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
            )
4 Likes

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.

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

1 Like

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

1 Like

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

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