Parsing JSON response from Google Maps - json

I needed to create a proxy-server to connect to the google maps webservicees, and I found a tutorial that does about 95% of what I need. The tutorial uses golang, I'm almost completely new to golang, and if I follow it exactly, it works fine. But the moment I try to change something from the tutorial, I'm obviously messing something up, lol.
The issue that I need right now is that the tutorial only parses 2 variables from the google-maps response, the latitude and longitude. For the rest of my app I ALSO need the place Id.
I'm receiving the response from google-maps, not a problem. If I parse it as
type placeResults struct {
Results []struct {
Geometry struct {
Location struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
} `json:"location"`
} `json:"geometry"`
} `json:"results"`
}
It works fine and gives me the latitude and longitude, no worries.
But if I instead try,
type placeResults struct {
Results []struct {
Geometry struct {
Location struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
} `json:"location"`
} `json:"geometry"`
id struct {
Id string `json:"id"`
}
} `json:"results"`
}
It tells me:
json: cannot unmarshal string into Go struct field .Id of type struct { Id string "json:\"id\"" }
Now the id variable isn't part of the geometry, but is a generic part of the response, so I figured this would be the correct syntax. Obviously I am wrong. But what IS the correct syntax to include this?

Google place API response looks like,
"geometry" : {
"location" : {
"lat" : -33.866651,
"lng" : 151.195827
},
"viewport" : {
"northeast" : {
"lat" : -33.8653881697085,
"lng" : 151.1969739802915
},
"southwest" : {
"lat" : -33.86808613029149,
"lng" : 151.1942760197085
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "4f89212bf76dde31f092cfc14d7506555d85b5c7",
So you need to declare id field as string, not struct. You need to change placeResult structure.
type modifiedPlaceResult struct {
Geometry struct {
Location struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
} `json:"location"`
} `json:"geometry"`
Id string `json:"id"`
}
try use modifiedPlaceResult struct for Unmarshaling data, everything would be ok.
I attached the example from Go playground: https://play.golang.org/p/Q4rM-jluoFe

Related

Unmarshall JSON with a [int]string map contained in an array

Im trying to unmarshall the following JSON into a struct, but there I am unable to translate the contents of the values field with the [[int,string]]
This is what I have so far:
type Response struct {
Metric struct {
Name string `json:"name,omitempty"`
Appname string `json:"appname,omitempty"`
} `json:"metric,omitempty"`
Values []map[int]string `json:"values,omitempty"`
}
The JSON file:
{
"metric":{
"name":"x444",
"appname":"cc-14-471s6"
},
"values":[
[
1508315264,
"0.0012116165566900816"
],
[
1508315274,
"0.0011871631158857396"
]
]
}
The data you showed should be unmarshaled to:
type Response struct {
Metric struct {
Name string `json:"name,omitempty"`
Appname string `json:"appname,omitempty"`
} `json:"metric,omitempty"`
Values [][]interface{} `json:"values,omitempty"`
}
If you want to to transfer it to map implement json.Unmarshaller interface - https://golang.org/pkg/encoding/json/#Unmarshaler
You can have something like:
type Item struct {
Key int
Val string
}
func(item *Item) UnmarshalJSON([]byte) error {
// TODO: implement
}
type Response struct {
Metric struct {
Name string `json:"name,omitempty"`
Appname string `json:"appname,omitempty"`
} `json:"metric,omitempty"`
Values []Item `json:"values,omitempty"`
}

Json unmarshal type model in golang

I have a RESTful service that returns response similar to show below:
"Basket" : {
"Count": 1,
"Fruits": {[
{
"Name":"Mango",
"Season":"Summer"
},
{
"Name":"Fig",
"Season":"Winter"}
]}
}
I am trying to create Go lang model to unmarshal the contents. Following is the code I have tried:
type Response struct {
Count int
Fruits []Fruit
}
type Fruit struct {
Name string
Season string
}
But when I marshal the Response object in my test code I don't see similar json. (https://play.golang.org/p/EGKqfbwFvW)
Marshalled data always appears as :
{
"Count":100,
"Fruits":[
{"Name":"Mango","Season":"Summer"},
{"Name":"Fig","Season":"Winter"}
]
}
Notice the Fruits appearing as array [] and not {[]} in original json. How can I model structs in golang for this response?
Your model is totally correct and valid, but the JSON object is not. "Fruits" doesn't have name if it should be key value pair or it should be wrapped in [] not {}.
JSON obj should be formatted like this:
{
"Basket" : {
"Count": 1,
"Fruits": [
{
"Name":"Mango",
"Season":"Summer"
},
{
"Name":"Fig",
"Season":"Winter"
}
]
}
}
And actually invalid json shouldn't work https://play.golang.org/p/yoW7t4NfI7
I would make 'Baskets' a struct within 'Response', create a 'BasketsData' struct, and give it all some labels.
type Fruit struct {
Name string `json:"Name"`
Season string `json:"Season"`
}
type BasketData struct {
Count int `json:"Count"`
Fruits []Fruit `json:"Fruits"`
}
type Response struct {
Basket BasketData `json:"Basket"`
}
This way you will get a top level JSON response when you marshall it.
fruitmania := []Fruit{{Name: "Mango", Season: "Summer"},
{Name: "Fig", Season: "Winter"}}
basket := Response{BasketData{Count: 100, Fruits: fruitmania}}
b, _ := json.Marshal(basket)
fmt.Println(string(b))
checkit-checkit out:
https://play.golang.org/p/TuUwBLs_Ql

How to unmarshal this nested JSON into go objects?

I have a JSON object similar to this one:
{
"prices": {
"7fb832f4-8041-4fe7-95e4-6453aeeafc93": {
"diesel": 1.234,
"e10": 1.234,
"e5": 1.234,
"status": "open"
},
"92f703e8-0b3c-46da-9948-25cb1a6a1514": {
"diesel": 1.234,
"e10": 1.234,
"e5": 1.234,
"status": "open"
}
}
I am not sure how to unmarshal this into an GO object without losing the unique ID field of each sub-item which is important information for me.
You can use a map with string keys to preserve the unique IDs of each sub-price:
type Object struct {
Prices map[string]*Price `json:"prices"`
}
type Price struct {
Diesel float32 `json:"diesel"`
E10 float32 `json:"e10"`
E5 float32 `json:"e5"`
Status string `json:"status"`
}
Then, for example, you could loop over the unmarshaled object:
for id, price := range o.Prices {
fmt.Printf("%s %v\n", id, price)
}
https://play.golang.org/p/aPhvGdtFC_
Use a map:
type Station struct {
Diesel float64
E10 float64
E15 float64
Status string
}
type Data struct {
Prices map[string]*Station
}
playground example

Golang : best way to unmarshal following json with string as keys

I have json like
{
"api_type" : "abc",
"api_name" : "xyz",
"cities" : {
"new_york" : {
"lat":"40.730610",
"long":"-73.935242"
},
"london" : {
"lat":"51.508530",
"long":"-0.076132"
},
"amsterdam" : {
"lat":"52.379189",
"long":"4.899431"
}
//cities can be multiple
}
}
I can use following struct to unmarshal
type MyJsonName struct {
APIName string `json:"api_name"`
APIType string `json:"api_type"`
Locations struct {
Amsterdam struct {
Lat string `json:"lat"`
Long string `json:"long"`
} `json:"amsterdam"`
London struct {
Lat string `json:"lat"`
Long string `json:"long"`
} `json:"london"`
NewYork struct {
Lat string `json:"lat"`
Long string `json:"long"`
} `json:"new_york"`
} `json:"locations"`
}
but my city names and numbers will be different in each response, what is a best way unmarshal this type of json where keys can be string which varies.
I would make the locations a map (although you have it called cities in the JSON):
type MyJsonName struct {
APIName string `json:"api_name"`
APIType string `json:"api_type"`
Locations map[string]struct {
Lat string
Long string
} `json:"locations"`
}

How can I convert JSON to work with CLLocationCoordinate2D in Swift

I used a web service and saved a JSON data into my jsonArray. Now I'm trying to apply the data into CLLocationCoordinate2D like this:
CLLocationCoordinate2D(latitude: self.jsonArray["JSONResults"][0]["lat"],longitude: self.jsonArray["JSONResults"][0]["long"])
Swift Compiler tells me:
Cannot invoke initializer for type 'CLLocationCoordinate2D' with an argument list of type (latitude: JSON, longitude: JSON)
I tried using as Int but it still doesn't work. How can I properly convert this appropriately?
Example of my JSON data:
{
"long" : "121.513358",
"tel" : "(02)2331-6960",
"lat" : "25.044976",
"add" : "xxx",
"region" : "yyy",
"name" : "zzz"
}
It looks like you're using the library SwiftyJSON to decode your JSON.
This library creates objects of type JSON, you have to extract their value before using it.
Since your values in the response seem to be Strings and you need Doubles for CLLocationCoordinate2D, this should work:
let lat = self.jsonArray["JSONResults"][0]["lat"].stringValue
let long = self.jsonArray["JSONResults"][0]["long"].stringValue
CLLocationCoordinate2D(latitude: Double(lat)!, longitude: Double(long)!)
In this example I'm using the SwiftyJSON non-optional getters stringValue. But you can also use the optional getters .string if the values could be nil:
if let lat = self.jsonArray["JSONResults"][0]["lat"].string, let long = self.jsonArray["JSONResults"][0]["long"].string, let latitude = Double(lat), let longitude = Double(long) {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}