I am trying to parse a json object into a struct, but integer values set to 0 won't work.
q := []byte(`{"string":"this is a string", "integer": 0}`)
type Test struct {
String string `json:"string,omitempty"`
Integer int `json:"integer,omitempty"`
}
var qq Test
if err := json.Unmarshal(q, &qq); err != nil {
panic(err)
}
queryStr, err := json.Marshal(qq)
if err != nil {
panic(err)
}
fmt.Println(string(queryStr))
// Output: {"string": "this is a string"}
if I set the integer to anything but 0, this works fine.
even if I Unmarshal the object and set the Integer field to 0, Marshalling it back removes the "integer" field.
Why? and how to get around this?
EDIT:
from what I gather from the comments, omitempty
triggers when value is 0. So now the disappearance makes sense.
I'm parsing json, editing it and forwarding it to another service, so this is unfortunate, especially as field not present defaults to other values than 0, and I would prefer not having to feed in the defaults for the downstream API.
So is there a way to omit empty values but keep 0?
or change empty to something else?
Do I need to have 2 structs: one for input and one for output?
Use a pointer for the fields, so that the zero value of the JSON type can be differentiated from the missing value.
type Test struct {
String *string `json:"string,omitempty"`
Integer *int `json:"integer,omitempty"`
}
https://play.golang.org/p/yvYSHxubLy
"omitempty" tag makes sense only for marshaling from struct to JSON. It skips empty values so they won't be in JSON. It doesn't affect unmarshaling in any way. Use pointers if you want to detect whether the field is specified in JSON or not. If the field is not specified, the pointer value will be nil.
as the docs says in https://golang.org/pkg/encoding/json/#Marshal
Struct values encode as JSON objects. Each exported struct field becomes a member of the object unless
- the field's tag is "-", or
- the field is empty and its tag specifies the "omitempty" option. The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero. The object's default key string is the struct field name but can be specified in the struct field's tag value. The "json" key in the struct field's tag value is the key name, followed by an optional comma and options.
so no, unless you implement your own marshaller for your struct
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With