Reputation: 807
I am trying to unmarshal a json with a nested json.
I am using this struct
type atomRequest struct {
Stream string `json:"stream"`
Data map[string]interface{} `json:"data"`
}
if the nested json is stringified, the Unmasrhaling fails and the value is nil
if the byte array that i am marshalling is with a non escape "data" The "Data" map is being populated correctly.
if the nested json is stringified, I get an empty Data map.
I am looking for a solution to unmarshal the nested data, whether its stringified or not.
The example: this input works:
{"stream":"foobar","data":{"errorID":112,"timestamp":1524737466}}
This input does not work:
{
"stream": "foo",
"data": "{\"cd3\":\"514\",\"cd8\":\"none\"}"
}
can you help?
thanks
Upvotes: 2
Views: 1082
Reputation: 121129
Use json.RawMessage to capture the varying field:
type atomRequest struct {
Stream string `json:"stream"`
RawData json.RawMessage `json:"data"`
Data map[string]interface{} `json:"-"`
}
Unmarshal the top-level JSON:
var req atomRequest
if err := json.Unmarshal(data, &req); err != nil {
// handle error
}
If data
is a string, unmarshal to remove the extra level of encoding:
if len(req.RawData) > 0 && req.RawData[0] == '"' {
var s string
if err := json.Unmarshal(req.RawData, &s); err != nil {
// handle error
}
req.RawData = json.RawMessage(s)
}
Finally, unmarshal to the map[string]interface{}
:
if err := json.Unmarshal(req.RawData, &req.Data); err != nil {
// handle error
}
Upvotes: 4