Ilya Ilya - 1 year ago 43
JSON Question

How can I know that the field is set to null?

I want to output an error if the field in json contains a value of null. How can I do it? I have tried "encoding/json". Maybe I need another library.

Code example:

package main

import (
"encoding/json"
"fmt"
"strings"
)

type Item struct {
Value *int
}


func main() {
var jsonBlob = `[
{},
{"Value": null},
{"Value": 0},
{"Value": 1}
]`
var items []Item

err := json.NewDecoder(strings.NewReader(jsonBlob)).Decode(&items)
if err != nil {
fmt.Println("error:", err)
}
for _, a := range items {
if a.Value != nil {
fmt.Println(*a.Value)
} else {
fmt.Println(a.Value)
}
}
}


I got:

<nil>
<nil>
0
1


I want:

<nil>
<error>
0
1


Please help. Many thanks!

Answer Source

If you want to control how a type is unmarshaled, you can implement json.Unmarshaler

Since a map allows you to tell the difference between an unset value, and a null value, unmarshaling first into a generic map[string]interface{} will allow you to inspect the values without tokenizing the JSON.

type Item struct {
    Value *int
}


func (i *Item) UnmarshalJSON(b []byte) error {
    tmp := make(map[string]interface{})

    err := json.Unmarshal(b, &tmp)
    if err != nil {
        return err
    }

    val, ok := tmp["Value"]
    if ok && val == nil {
        return errors.New("Value cannot be nil")

    }
    if !ok {
        return nil
    }

    f, ok := val.(float64)
    if !ok {
        return fmt.Errorf("unexpected type %T for Value", val)
    }

    n := int(f)
    i.Value = &n
    return nil
}

https://play.golang.org/p/MNDsQpfEJA

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download