-1

What I am trying to do
I am parsing a JSON HTTP response based on this answer to a similar question. My code is able to parse the JSON without any error but is unable to read the values and store them in the provided variable. This has been puzzling me for the last 2 hours and it might be due to a trivial reason that I am overlooking here.

CODE

type ImporterResponse struct {
    results []packagemeta `json:"results"`
}

type packagemeta struct {
    path     string `json:"path"`
    synopsis string `json:"synopsis,omitempty"`
    count    int    `json:"import_count,omitempty`
}


func main() {

    res := []byte(`{"results":[{"path":"4d63.com/randstr/lib/randstr","import_count":0,"synopsis":"Package randstr generates random strings (e.g."},{"path":"bitbucket.org/pcas/tool/mathutil","import_count":0}]}`)
    fmt.Println("Decoding the JSON")

    r := bytes.NewReader(res)
    decoder := json.NewDecoder(r)

    packageimporters := &ImporterResponse{}
    err := decoder.Decode(packageimporters)

    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Packageimporters: %+v", packageimporters)
    fmt.Println(len(packageimporters.results))
}

Link to Playground: https://play.golang.org/p/NzLl7Ujo2IJ

What I want:

  1. How to fix this?
  2. Why is no error message raised if JSON is not parsed properly?

P.S: I understand that this question has been asked before and there are possible solutions available but none of them work for me. Hence, I have made this post.

Kshitij Saraogi
  • 6,821
  • 8
  • 41
  • 71

1 Answers1

3

You need to make your struct fields exported, otherwise the json package cannot access them.

Please read JSON and go for more details, specifically this paragraph:

The json package only accesses the exported fields of struct types (those that begin with an uppercase letter). Therefore only the the exported fields of a struct will be present in the JSON output.

And this one for more details:

How does Unmarshal identify the fields in which to store the decoded data? For a given JSON key "Foo", Unmarshal will look through the destination struct's fields to find (in order of preference):

An exported field with a tag of "Foo" (see the Go spec for more on struct tags),

An exported field named "Foo", or

An exported field named "FOO" or "FoO" or some other case-insensitive match of "Foo".

So your struct should really be:

type Packagemeta struct {
    Path     string `json:"path"`
    Synopsis string `json:"synopsis,omitempty"`
    Count    int    `json:"import_count,omitempty`
}
Marc
  • 19,394
  • 6
  • 47
  • 51