23

I have a json response from a api as map[message:Login Success. userid:1]

Server:

c.JSON(200, gin.H{"message": "Login Success.", "userid": 1})

Client:

var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)

msg, ok := result["message"].(string)
if !ok {
    msg = "Something went wrong."
}
userID, ok := result["userid"].(int)
if !ok {
    userID = 0
}

But userID, ok := result["userid"].(int) always fails. I've even tried using:

switch v := x.(type) {
case nil:
    fmt.Println("x is nil")          
case int: 
    fmt.Println("x is", v)           
case bool, string:
    fmt.Println("x is bool or string")
default:
    fmt.Println("type unknown")      
}

And it just gave me unknown. Why is the integer not being taken as integer?


It looks like its treating the value as float64.

majidarif
  • 18,694
  • 16
  • 88
  • 133
  • Maybe it is a uint, or int8, or another int type – Sean F Mar 30 '19 at 23:43
  • @SeanF I doubt that's the case. I just tried `c.JSON(200, gin.H{"message": "Login Success.", "userid": int(1)})` and its still failing. – majidarif Mar 30 '19 at 23:45
  • Why would that change anything? – Sean F Mar 30 '19 at 23:47
  • Why don't you just get the type and tell me what the type is because it is not int, that is for sure https://stackoverflow.com/questions/20170275/how-to-find-a-type-of-an-object-in-go – Sean F Mar 30 '19 at 23:49
  • Ok I just saw it. Its `float64` but why is it treating it as float? – majidarif Mar 30 '19 at 23:53
  • Call the programmer on the phone and ask him why he chose float64 instead of int – Sean F Mar 30 '19 at 23:56
  • Most likely he sends all numbers across as float64 because it was easy to do it that way – Sean F Mar 30 '19 at 23:57
  • You mean the `gin.H` ints are getting packed as floats? – majidarif Mar 31 '19 at 00:00
  • Maybe, who knows what gin.H does. It is the most likely scenario. Far more likely than your assertion that golang type assertion does not work with int. Also more likely than the possibility that the json encode or decode converts int to float. – Sean F Mar 31 '19 at 00:05
  • I'm pretty sure it just uses the `json.Marshall` function to encode whatever is in `gin.H` and `gin.H` is just a `map[string]interface{}` there has got to be another reason. – majidarif Mar 31 '19 at 00:09
  • You make far too many assumptions. Nik just proved this latest one wrong. – Sean F Mar 31 '19 at 00:18

1 Answers1

29

Here you can find the explanation why you are getting float64 and not int:

Check doc for Decode

See the documentation for Unmarshal for details about the conversion of JSON into a Go value.

And there see

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

float64, for JSON numbers
Nik
  • 2,885
  • 2
  • 25
  • 25