I ran into some problem with unmarshalling string back to struct object when the object has a nested array of struct objects. I use the following code as a demo for my problem:
The json string is
const myStr = `{
"name": "test_session1",
"shared_items:": [
{
"id": 0,
"name": ".aspnet"
},
{
"id": 1,
"name": ".bash_profile"
}
]
}`
I have two structs as following with Session being the parent and SharedItem being the associated child(ren):
type Session struct {
ID uint64 `json:"id"`
Name string `json:"name,omitempty"`
SharedItems []SharedItem `json:"shared_items"`
}
type SharedItem struct {
ID uint64 `json:"id"`
Name string `json:"name"`
}
I tried the following to unmarshal the json string, but it looks like the nested array of SharedItem objects are missing, as I saw sess object has 0 shared items, which is not what I expected.
func main() {
var sess Session
if err := json.Unmarshal([]byte(myStr), &sess); err != nil {
panic(err)
}
fmt.Printf("sess name is: %s, and has %d shared items
", sess.Name, len(sess.SharedItems)) // printed: sess name is test_session1, and has 0 shared items
}
Here's the link to my go playground: https://play.golang.org/p/a-y5T3tut6g
Golang Spec for json unmarshal describe it all
To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don't have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).
In the json provided the json object for shared items has :
colon in it as we can see it is shared_items:
not shared_items
which is our json tag
"shared_items:": [
{
"id": 0,
"name": ".aspnet"
},
{
"id": 1,
"name": ".bash_profile"
}
]
Either remove :
or append into your struct json tag to match the same.
package main
import (
"fmt"
"encoding/json"
)
type Session struct {
Name string `json:"name,omitempty"`
SharedItems []SharedItem `json:"shared_items"`
}
type SharedItem struct {
ID uint64 `json:"id"`
Name string `json:"name"`
}
const myStr = `{"name":"test_session1","shared_items":[{"id":0,"name":".aspnet"},{"id":1,"name":".bash_profile"}]}`
func main() {
var sess Session
if err := json.Unmarshal([]byte(myStr), &sess); err != nil {
panic(err)
}
fmt.Println(sess)
fmt.Printf("sess name is: %s, and has %d shared items
", sess.Name, len(sess.SharedItems))
}