# Tips on JSON decoding

**URL:** <https://discourse.elm-lang.org/t/tips-on-json-decoding/6480>\
**Category:** Learn\
**Created:** [November 3, 2020, 6:42pm UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480 "2020-11-03T18:42:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gorgoroth](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gorgoroth/32/3355_2.png) [@gorgoroth](https://discourse.elm-lang.org/u/gorgoroth)\
**Post date:** [November 3, 2020, 6:42pm UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480/1 "2020-11-03T18:42:26Z")

</div>

Hi all, I have a couple of questions on the matter:

1. I have a JSON where some fields are generally numbers (ie 2020) but sometimes they are stored as strings which represent a number (ie “2020”).  
How to silently decode those type of fields into an Elm Int?

2. Some JSON data comes with different structure. Sometimes it is a simple object which can be decoded as a Elm Record, other times it could be a list of different objects which should be decoded as List of Records. (in the two cases, even the single objects have different formats).

Ie:

{“prop1”: “”, “prop2”: }

or

[{“prop1”: “”, “prop2”: , “prop3”: “”}, …]

I have tried to model this situation with types, but I’m stuck on decoding.

something like the following:

```
type alias MetadataType1 =
 { prop1: String
 , prop2: Int
 }

type alias MetadataType2 =
 { prop1: String
 , prop2: Int
 , prop3: String
 }

type Metadata
   = SingleMetadata MetadataType1
   | MultiMetadata (List MetadataType2)

-- the object which should be the result of decoding where metadata can be of different types
type alias JsonData =
  { name: String
  , metadata: Metadata
  }

```

Thanks in advance

---

<div class="post-metadata">

**Author:** ![bob-shelline](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/bob-shelline/32/465_2.png) [@bob-shelline](https://discourse.elm-lang.org/u/bob-shelline)\
**Post date:** [November 3, 2020, 6:48pm UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480/2 "2020-11-03T18:48:27Z")

</div>

I believe that the `oneOf` function from Json.Decode is designed to help with this:

> **[Json.Decode - json 1.1.3](https://package.elm-lang.org/packages/elm/json/latest/Json-Decode#oneOf)**

---

<div class="post-metadata">

**Author:** ![50kudos](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/50kudos/32/861_2.png) [@50kudos](https://discourse.elm-lang.org/u/50kudos)\
**Post date:** [November 4, 2020, 2:08am UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480/3 "2020-11-04T02:08:14Z")

</div>

Yep `oneOf` is the way to go:

```elm
type alias MetadataType1 =
    { prop1 : String
    , prop2 : Int
    }

type alias MetadataType2 =
    { prop1 : String
    , prop2 : Int
    , prop3 : String
    }

type Metadata
    = SingleMetadata MetadataType1
    | MultiMetadata (List MetadataType2)

-- the object which should be the result of decoding where metadata can be of different types

type alias JsonData =
    { name : String
    , metadata : Metadata
    }

jsondataDecoder : Decoder JsonData
jsondataDecoder =
    D.map2 JsonData
        (D.field "name" D.string)
        (D.field "metadata" metaDecoder)

metaDecoder : Decoder Metadata
metaDecoder =
    D.oneOf
        [ D.map SingleMetadata meta1Decoder
        , D.map MultiMetadata (D.list meta2Decoder)
        ]

meta1Decoder : Decoder MetadataType1
meta1Decoder =
    D.map2 MetadataType1
        (D.field "prop1" D.string)
        (D.field "prop2" D.int)

meta2Decoder : Decoder MetadataType2
meta2Decoder =
    D.map3 MetadataType2
        (D.field "prop1" D.string)
        (D.field "prop2" D.int)
        (D.field "prop3" D.string)

```

---

<div class="post-metadata">

**Author:** ![gorgoroth](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gorgoroth/32/3355_2.png) [@gorgoroth](https://discourse.elm-lang.org/u/gorgoroth)\
**Post date:** [November 4, 2020, 7:30am UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480/4 "2020-11-04T07:30:26Z")

</div>

Thanks both for the suggestion. It knew about oneOf but for some reason it has not been the first idea which came to my mind.  
I am quite a beginner.

---

<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, 2020, 7:30am UTC](https://discourse.elm-lang.org/t/tips-on-json-decoding/6480/5 "2020-11-14T07:30:30Z")

</div>

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