8
votes

I am trying to get field values from an interface in Golang. The interface is initially an empty interface which is getting its values from a database result. The DB query is working fine.

The only thing I need is that I need to get the field value of the interface. Here is my code:

s := reflect.ValueOf(t)
    for i := 0; i < s.Len(); i++ {
        fmt.Println(s.Index(i))
    }

where t is an interface having following values:

map[id:null count:1]

I want value of "count" like simply 1.

My problem is that the Index() method is returning a panic because it needs a struct and I dont have any struct here. So what should I do to get interface value? Is there any solution to iterate over an interface to get field values with or without Golang's reflection package?

Edit

After getting the value for count I need to parse it to json.

Here is my code:

type ResponseControllerList struct{
    Code            int             `json:"code"`
    ApiStatus       int             `json:"api_status"`
    Message         string          `json:"message"`
    Data            interface{}     `json:"data,omitempty"`
    TotalRecord     interface{}     `json:"total_record,omitempty"`
}
response := ResponseControllerList{}
ratingsCount := reflect.ValueOf(ratingsCountInterface).MapIndex(reflect.ValueOf("count"))
fmt.Println(ratingsCount)

response = ResponseControllerList{
                200,
                1,
                "success",
                nil,
                ratingsCount,
            }
GetResponseList(c, response)

func GetResponseList(c *gin.Context, response ResponseControllerList) {
    c.JSON(200, gin.H{
        "response": response,
    })
}

The above code is being used to get the ratingCount in JSON format to use this response as API response. In this code, I am using the GIN framework to make HTTP request to API.

Now the problem is that when I am printing the variable ratingsCount, its displaying the exact value of count in terminal what I need. But when I am passing it to JSON, the same variable gives me the response like:

{
    "response": {
        "code": 200,
        "api_status": 1,
        "message": "Success",
        "total_record": {
            "flag": 148
        }
    }
}

What is the way to get the count's actual value in JSON ?

1
"Index() method is returning a panic because it needs a struct" is wrong. Index works on slices and arrays. Can you explain more in depth what the problem is? E.g. your t interface looks like JSON and not like a Go interface type? - Volker
Actually I was parsing the interface to json. Now I have edited the interface. Index() is panicking because its getting a map. Map is not defined to work with Index. Right ? I just want to get "count" field value from interface. - Amandeep kaur
thanks @Volker, its returning me the count when I am printing it. But its giving me { flag: 148 } when I am parsing it to JSON. Can you Explain me the reason for it. Is it connected to reflection? - Amandeep kaur
I have to admit I do not understand what your "parsing to JSON" actually is. You did not show code and it seems rather strange to me. If you need further help you will have to come up with a proper problem description (parse to JSON is not helpful). - Volker

1 Answers

15
votes

You can use type assertion instead of reflection. It is generally better to avoid reflection whenever you can.

m, ok := t.(map[string]interface{})
if !ok {
    return fmt.Errorf("want type map[string]interface{};  got %T", t)
}
for k, v := range m {
    fmt.Println(k, "=>", v)
}

If you really want to use reflection, you can do something like this:

s := reflect.ValueOf(t)
for _, k := range s.MapKeys() {
    fmt.Println(s.MapIndex(k))
}

Update to reply to your latest update

It does not return what you expect because it returns a reflect.Value. If you want an integer value, you have to use ratingsCount.Int().

But as I said before, don't use reflection. Use the first solution with type assertion and just get the count with m["count"].

I posted working example there using type assertion: https://play.golang.org/p/9gzwtJIfd7