Reputation: 2101
package main
import (
"encoding/json"
"fmt"
)
type City struct {
City string `json:"City"`
Size int `json:"Size"`
}
type Location struct {
City City
State string `json:"State"`
}
func main() {
city := City{City: "San Francisco", Size: 8700000}
loc := Location{}
loc.State = "California"
loc.City = city
js, _ := json.Marshal(loc)
fmt.Printf("%s", js)
}
Outputs the following:
{"City":{"City":"San Francisco","Size":8700000},"State":"California"}
The intended output I want is:
{"City":"San Francisco","Size":8700000,"State":"California"}
I've read this blog post for custom JSON Marshalling, but I can't seem to get it to work for a struct with another embedded struct.
I tried flattening the struct by defining a custom MarshalJSON
function but I still get the same nested output:
func (l *Location) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
City string `json:"City"`
Size int `json:"Size"`
State string `json:"State"`
}{
City: l.City.City,
Size: l.City.Size,
State: l.State,
})
}
Upvotes: 3
Views: 1192
Reputation: 120931
Use an anonymous field to flatten the JSON output:
type City struct {
City string `json:"City"`
Size int `json:"Size"`
}
type Location struct {
City // <-- anonymous field has type, but no field name
State string `json:"State"`
}
The MarshalJSON
method is ignored in the question because code encodes a Location
value, but the MarshalJSON
method is declared with a pointer receiver. Fix by encoding a *Location
.
js, _ := json.Marshal(&loc) // <-- note &
Upvotes: 4