Question

I am trying to unmarshal json that contains ints encoded as strings. Using tags to specify that the field is encoded as a string works, but I am running into issues when the field is null. The main problem, it seems, is that the null is not encoded as a string so the parser ignores it and keeps going. The problem is that it jams in the previously decoded value for some reason.

Any ideas on how I can get this parsing correctly?

I have the following code:

package main

import (
    "encoding/json"
    "log"
)

type Product struct {
    Price int `json:",string,omitempty"`
}

func main() {
    data := `
[
{"price": "1"},
{"price": null},
{"price": "2"}
]
`

    var products []Product
    if err := json.Unmarshal([]byte(data), &products); err != nil {
        log.Printf("%#v", err)
    }
    log.Printf("%#v", products)

}

Output:

[]main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}

Code on go playground

Was it helpful?

Solution

Feels like a bug in the json package.

You can work around it with a custom Unmarshaller, like this, although it may be annoying if you've got a complex struct:

func (p *Product) UnmarshalJSON(b []byte) error {
   m := map[string]string{}
   err := json.Unmarshal(b, &m)
   if err != nil {
      return err
   } 
   if priceStr, ok := m["price"]; ok {
      p.Price, _ = strconv.Atoi(priceStr)
   }
   return nil
}

http://play.golang.org/p/UKjfVqHCGi

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top