I'm trying read JSON data from web, but that code returns empty result. I'm not sure what I'm doing wrong here.
package main
import "os"
import "fmt"
import "net/http"
import "io/ioutil"
import "encoding/json"
type Tracks struct {
Toptracks []Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr []Attr_info
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable []Streamable_info
Artist []Artist_info
Attr []Track_attr_info
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
func get_content() {
// json data
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
res, err := http.Get(url)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
var data Tracks
json.Unmarshal(body, &data)
fmt.Printf("Results: %v\n", data)
os.Exit(0)
}
func main() {
get_content()
}
The results from
json.Unmarshal
(intovar data interface{}
) do not directly match your Go type and variable declarations. For example,Output:
The ideal way is not to use ioutil.ReadAll, but rather use a decoder on the reader directly. Here's a nice function that gets a url and decodes its response onto a
target
structure.Example use:
You should not be using the default *http.Client structure in production as this answer originally demonstrated! (Which is what http.Get/etc call to). The reason is that the default client has no timeout set; if the remote server is unresponsive, you're going to have a bad day.
You need upper case property names in your structs in order to be used by the json packages.
Upper case property names are
exported properties
. Lower case property names are not exported.You also need to pass the your data object by reference (
&data
).Your Problem were the slice declarations in your data
structs
(except forTrack
, they shouldn't be slices...). This was compounded by some rather goofy fieldnames in the fetched json file, which can be fixed via structtags, see godoc.The code below parsed the json successfully. If you've further questions, let me know.