3

I'm new to golang and I'd like to get a json object into my code:

func getUserRandking() []KVU {    
    url := "http://127.0.0.1:8080/users"

    spaceClient := http.Client{         Timeout: time.Second * 10, 
    }

    req, err := http.NewRequest(http.MethodGet, url, nil)
    if err != nil {
        log.Fatal(err)
    }

    req.Header.Set("User-Agent", "spacecount-tutorial")

    res, getErr := spaceClient.Do(req)
    if getErr != nil {
        log.Fatal(getErr)
    }

    body, readErr := ioutil.ReadAll(res.Body)
    if readErr != nil {
        log.Fatal(readErr)
    }

    var users1 []KVU
    jsonErr := json.Unmarshal(body, &users1)
    if jsonErr != nil {
        log.Fatal(jsonErr)
    }

    fmt.Println(users1)

    return users1

}

but I get this runtime error

json: cannot unmarshal string into Go value of type []main.KVU exit status 1

The json that I'm trying to import is like this:

{
  "name": "userslist",
  "children": [
    {
      "name": "cat",
      "value": 1,
      "url": "http://example.com/1.jpg"
    },
    {
      "name": "dog",
      "value": 2,
      "url": "http://example.com/2.jpg"
    }
  ]
}

I have tried different type definitions like Users below:

type KVU struct {
    Key   string `json:"name"`
    Value int    `json:"value"`
    Url   string `json:"url"`
}

type Users struct {
    Name     string `json:"name"`
    Children []KVU  `json:"children"`
}

But that also leads to:

json: cannot unmarshal string into Go value of type []main.Users

How can I fix this?

1
  • 1
    The structure of the Go data structure must match the JSON. Your JSON is an object so marshal into a struct and not into a slice (which would be appropriate for a JSON array).
    – Volker
    Jul 23, 2018 at 12:28

1 Answer 1

6

The error is because you have to create Users struct rather than KUV for unmarshalling the JSON. Since []KVU is a slice which will unmarshal the array of children which is an array of Objects. Also you need to parse the Json returned from the server to remove escape characters like /. Use strconv.Unquote to manage with escaped JSON.

func Unquote(s string) (string, error)

Unquote interprets s as a single-quoted, double-quoted, or backquoted Go string literal, returning the string value that s quotes. (If s is single-quoted, it would be a Go character literal; Unquote returns the corresponding one-character string.)

Check below working Code:

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type KVU struct {
    Key   string `json:"name"`
    Value int    `json:"value"`
    Url   string `json:"url"`
}

type Users struct {
    Name     string `json:"name"`
    Children []KVU  `json:"children"`
}

func main() {
    result := getUserRandking()
    fmt.Println(result)
}

func getUserRandking() []KVU{
    input := `"{\"name\":\"userslist\",\"children\":[{\"name\":\"kachalmooferfer\",\"value\":444,\"url\":\"http://pbs.twimg.com/p‌​rofile_images/989898400609992704/UE8HiRVx_normal.jpg\"},{\"name\":\"patrick_jane7‌​7\",\"value\":407,\"url\":\"http://pbs.twimg.com/profile_images/94467727094959308‌​9/zv62U1ch_normal.jpg\"},{\"name\":\"Pensylvani\",\"value\":213,\"url\":\"http://‌​pbs.twimg.com/profile_images/1018010357892198400/Rw06UWvY_normal.jpg\"}]}"`
    var val []byte = []byte(input)
    jsonInput, err := strconv.Unquote(string(val))
    if err !=nil{
        fmt.Println(err)
    }
    var resp Users
    json.Unmarshal([]byte(jsonInput), &resp)
    // Return below struct slice for Children from the function 
    return resp.Children
}

Go Playground Example

12
  • Well this removes the original error but now I get: json: cannot unmarshal string into Go value of type main.Users exit status 1
    – Babr
    Jul 23, 2018 at 12:31
  • Let me check because I have tested in on Go playground it is working fine.
    – Himanshu
    Jul 23, 2018 at 12:32
  • Yea, but I need to get the json inside getUserRandking function. Appreciate if you can revamp the code.
    – Babr
    Jul 23, 2018 at 12:33
  • Well, it there: The code sample starts with func getUserRandking() {... How can you see it?
    – Babr
    Jul 23, 2018 at 12:36
  • 1
    @Babr, simply return resp.Children then.
    – Peter
    Jul 23, 2018 at 12:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.