0

I have a json data that looks like this:

    [
      {
        lat: "41.189301799999996",
        lon: "11.918255998031015",
        display_name: "Some place",
        address: {
          address: "Address",
          country: "Country",
          country_code: "CC"
        },
        geojson: {
          type: "Polygon",
          coordinates: [
             [
               [14.4899021,41.4867039],
               [14.5899021,41.5867039],
             ]
          ]
        }
     }
   ]

I would like to parse this data, take the first element from this array and transform it into a new struct that would look like this:

type Location struct {
    Name        string
    Country     string
    CountryCode string
    Center      Coordinate
    Coordinates []Coordinate
}

I have defined Coordinate type like this:

type Coordinate struct {
    Lat string `json:"lat"`
    Lng string `json:"lon"`
}

But, if try to parse this like this:

bytes, err := ioutil.ReadAll(res.Body)

if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
}

var locations [0]Location

if err := json.Unmarshal(bytes, &locations); err != nil {
    fmt.Println("Error parsing json", err)
}

fmt.Println(locations)

But, that gives me this in the terminal:

[{   { } []}]

How can I parse this kind of json structure and transform it to the location kind of structure?

2
  • 1
    You should define a struct that matches the JSON input, unmarshal to that, and manually construct the Location struct from the unmarshaled values. Commented Apr 27, 2020 at 22:16
  • How would a struct that matches nested values look like then, country code in this example? Commented Apr 27, 2020 at 22:21

2 Answers 2

1

You should use a struct that matches the input document to unmarshal:

type Entry struct {
  Lat string `json:"lat"`
  Lon string `json:"lon"`
  DisplayName string `json:"display_name"`
  Address struct {
      Address string `json:"address"`
      Country string `json:"country"`
      Code string `json:"country_code"`
  } `json:"address"`
  Geo struct {
     Type string `json:"type"`
     Coordinates [][][]float64 `json:"coordinates"`
  } `json:"geojson"`
}

Then unmarshal into an array of Entry:

var entries []Entry
json.Unmarshal(data,&entries)

And, use entries to construct Locations

Sign up to request clarification or add additional context in comments.

Comments

1

You need to be more precise with your structure to which you Unmarshal. You also need to have double quotes around your keys per the official JSON spec. Omitting the quotes is only for within JavaScript, JSON requires those.

One last thing, I know it's silly, but the final comma after the last inner array was also invalid, had to remove that:

package main

import (
    "encoding/json"
    "fmt"
)

type Location struct {
    Lat         string     `json:"lat"`
    Lng         string     `json:"lon"`
    DisplayName string     `json:"display_name"`
    Address     Address    `json:"address"`
    GeoJSON     Geo        `json:"geojson"`
}

type Address struct {
    Address     string `json:"address"`
    Country     string `json:"country"`
    CountryCode string `json:"country_code"`
}

type Geo struct {
    Type        string         `json:"type"`
    Coordinates [][]Coordinate `json:"coordinates"`
}

type Coordinate [2]float64

func main() {
    inputJSON := `
    [
          {
            "lat": "41.189301799999996",
            "lon": "11.918255998031015",
            "display_name": "Some place",
            "address": {
              "address": "123 Main St.",
              "country": "USA",
              "country_code": "+1"
            },
            "geojson": {
              "type": "Polygon",
              "coordinates": [
                [
                  [14.4899021,41.4867039],
                  [14.5899021,41.5867039]
                ]
              ]
            }
          }
        ]`

    var locations []Location

    if err := json.Unmarshal([]byte(inputJSON), &locations); err != nil {
        panic(err)
    }

    fmt.Printf("%#v\n", locations)
}

You can run this on the Go Playground too!

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.