0

I am json.Decode()'ing (forgive the shorthand) a json response from an api into a large struct. Within that struct are a few types that are of type []interface{}. I can't figure out how to extract any data from those special nested structs. I have tried using a case switch type checking solution but came up empty handed still. Can someone share their experience with a similar case or point me in the right direction?

m := new(largestruct)
if err := json.NewDecoder(resp.Body).Decode(&m); err != nil{
return err
}

The struct field for interface is:

Strings []interface{} `json:"strings"`
Himanshu
  • 12,071
  • 7
  • 46
  • 61
trophyfish
  • 11
  • 2
  • 2
    Can you provide sample JSON data and explain which types you would like to decode that data into? – maerics Aug 06 '18 at 15:37
  • https://stackoverflow.com/questions/44027826/convert-interface-to-string-in-golang found this. My problem being the response is always "[ ]" so maybe there isn't anything to get anyway.. – trophyfish Aug 06 '18 at 16:17
  • @trophyfish Please post the json response in your question post. – Himanshu Aug 06 '18 at 16:44

1 Answers1

2

Using the switch case you can fetch the value underlying the interface. The function will run recursively until it gets the original type of the parsed json.

func fetchValue(value interface{}) { // pass the interface value from the struct in this function as it will run recursively to get the value.
    switch value.(type) {
    case string:
        fmt.Printf("%v is an string \n ", value.(string))
    case bool:
        fmt.Printf("%v is bool \n ", value.(bool))
    case float64:
        fmt.Printf("%v is float64 \n ", value.(float64))
    case []interface{}:
        fmt.Printf("%v is a slice of interface \n ", value)
        for _, v := range value.([]interface{}) {
            fetchValue(v)
        }
    case map[string]interface{}:
        fmt.Printf("%v is a map \n ", value)
        for _, v := range value.(map[string]interface{}) {
            fetchValue(v)
        }
    default:
        fmt.Printf("%v is unknown \n ", value)
    }
}

The reason behind the types in switch to be limited is defined in the golang spec for unmarshal where it is clearly described what values the json will parse into when unmarshaling using interface{}:

To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
Himanshu
  • 12,071
  • 7
  • 46
  • 61