Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Unable to unmarshal data in go

I got this error:
cannot unmarshal string into Go struct field Attributes.length of type float64
but I’m trying to unmarshal the field with the lowercase letter which is indeed a number.
Why the error?

Notice the tag: json:"length", which should get me the lower case field, right?

Here is the playground, if you want to reproduce it https://go.dev/play/p/v7EWz5OGou4

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


import (
    "encoding/json"
    "fmt"
)

const problematicData = `{
    "length": 3350,
    "Length": "3350"
}`

type Attributes struct {
    Length float64 `json:"length"`
}

func main() {
    var attributes Attributes
    err := json.Unmarshal([]byte(problematicData), &attributes)
    fmt.Println("error:", err)
}

>Solution :

Golang’s Unmarshal function is case in-sensitive by default. See https://pkg.go.dev/encoding/json#Unmarshal

preferring an exact match but also accepting a case-insensitive match

In order to get this working in your case, you’ll need to implement a custom unmarshaller.

The following will accept the length key from the json. Playground: https://go.dev/play/p/OAUdMBc0Szi

package main

import (
    "encoding/json"
    "fmt"
)

const problematicData = `{
    "length": 3350,
    "Length": "3350"
}`

type Attributes struct {
    Length float64 `json:"length"`
}

func (b *Attributes) UnmarshalJSON(data []byte) error {
    var v map[string]any
    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }
    for key, v := range v {
        if key != "length" {
            continue
        }
        if floatValue, ok := v.(float64); ok {
            b.Length = floatValue
        }
    }
    return nil
}

func main() {
    var attributes Attributes
    err := json.Unmarshal([]byte(problematicData), &attributes)
    fmt.Println("error:", err, attributes)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading