I am practicing JSON parsing and I encountered this kind of JSON
{
"data": {
"Location": "[{\"id\":\"asdiqwe321\",\"name\":\"Manila\",\"lat\":25.42952,\"long\":-96.7960712,\"rating\":3,\"address\":\"Manila Ph\"},{\"place_id\":\"zzxdasdqwe1235as\",\"name\":\"Quezon City Ph.\",\"lat\":12.523562,\"long\":24.663415,\"rating\":1,\"address\":\"Quezon City Ph\"},{\"place_id\":\"rtiDFSDQ1321\",\"name\":\"Makati\",\"lat\":32.151236,\"long\":21.24124561,\"rating\":3.5,\"address\":\"Makati PH\"}]"
}
}
I have a model and want to cast it there:
export interface Location{
place_id: string,
name: string,
lat: number,
long: number,
rating: number,
address: number
}
This is my first time to encountered this type of JSON. I hope someone will help me and understand what is it.
That's not a JSON Object, that's a string. The \ character is used to escape the double quote ", otherwise JavaScript would interpret the double quote as the end of the string and would throw a parsing error.
If you want to access the string as an object, you need to parse it using JSON.parse:
const obj = {
"data": {
"Location": "[{\"id\":\"asdiqwe321\",\"name\":\"Manila\",\"lat\":25.42952,\"long\":-96.7960712,\"rating\":3,\"address\":\"Manila Ph\"},{\"place_id\":\"zzxdasdqwe1235as\",\"name\":\"Quezon City Ph.\",\"lat\":12.523562,\"long\":24.663415,\"rating\":1,\"address\":\"Quezon City Ph\"},{\"place_id\":\"rtiDFSDQ1321\",\"name\":\"Makati\",\"lat\":32.151236,\"long\":21.24124561,\"rating\":3.5,\"address\":\"Makati PH\"}]"
}
};
const locationString = obj.data.Location;
const locationObject = JSON.parse(locationString);
console.log(locationObject[0].id);
If you don't parse it, instead, obj.data.Location is just a string:
const obj = {
"data": {
"Location": "[{\"id\":\"asdiqwe321\",\"name\":\"Manila\",\"lat\":25.42952,\"long\":-96.7960712,\"rating\":3,\"address\":\"Manila Ph\"},{\"place_id\":\"zzxdasdqwe1235as\",\"name\":\"Quezon City Ph.\",\"lat\":12.523562,\"long\":24.663415,\"rating\":1,\"address\":\"Quezon City Ph\"},{\"place_id\":\"rtiDFSDQ1321\",\"name\":\"Makati\",\"lat\":32.151236,\"long\":21.24124561,\"rating\":3.5,\"address\":\"Makati PH\"}]"
}
};
console.log(typeof obj.data.Location);
You usually need to stringify or parse objects for serializations purpose.
It is Array of object of type Location in serialized form.
var response = {
"data": {
"Location": "[{\"id\":\"asdiqwe321\",\"name\":\"Manila\",\"lat\":25.42952,\"long\":-96.7960712,\"rating\":3,\"address\":\"Manila Ph\"},{\"place_id\":\"zzxdasdqwe1235as\",\"name\":\"Quezon City Ph.\",\"lat\":12.523562,\"long\":24.663415,\"rating\":1,\"address\":\"Quezon City Ph\"},{\"place_id\":\"rtiDFSDQ1321\",\"name\":\"Makati\",\"lat\":32.151236,\"long\":21.24124561,\"rating\":3.5,\"address\":\"Makati PH\"}]"
}
}
You have to parse it.
var locationData : Array<Location> = JSON.Parse(response.data.Location);
Related
I'm trying to retrieve data from a local JSON file like this:
[{
"name": "John",
"lastname": "Doe",
"age": "30"
},
{
"name": "Jane",
"lastname": "Doe",
"age": "20"
}
,
{
"name": "Baby",
"lastname": "Doe",
"age": "3"
}]
The user, using a datapicker can select name and/or lastname
import SwiftUI
struct ContentView : View {
var names = ["John", "Jane", "Baby"]
var lastnames = ["Doe", "Boe"]
#State private var selectedNameItem = 0
#State private var selectedLastNameItem = 0
var body: some View {
VStack {
Picker(selection: $selectedNameItem, label: Text("Names:")) {
ForEach(0 ..< names.count) {
Text(self.names[$0]).tag($0)
}
}
Text("Your choice: ")
+ Text("\(names[selectedNameItem])")
}
VStack {
Picker(selection: $selectedLastNameItem, label: Text("LastName:")) {
ForEach(0 ..< lastnames.count) {
Text(self.lastnames[$0]).tag($0)
}
}
Text("Your choice: ")
+ Text("\(lastnames[selectedLastNameItem])")
}
}
}
Once selected the name/lastyname (as parameter) I want to show a text that said for example: "John Doe is 30 years old"
How I can read the data from JSON and return exactly the age of the user selected without list all the elements?
Thanks a lot,
Fabrizio
To start, I recommend making a struct to represent your JSON structure. Try the following:
struct Person: Codable, Hashable {
let name: String
let lastname: String
let age: String
}
typealias People = [Person]
I usually make a typealias to handle the array version of my data. Once you have defined your data structure to match your JSON, I usually extend my data to make loading from JSON easy.
extension Person {
static func load(fromJson json: URL) -> People {
guard let data = try? Data(contentsOf: json) else {
preconditionFailure("Unable to read data from URL")
}
let jsonDecoder = JSONDecoder()
var people = People()
do {
people = try jsonDecoder.decode(People.self, from: data)
} catch {
print(error)
}
return people
}
}
There are more generic ways to do this to support a wider swath of models, but for your example, this is quick and easy.
Now that you have an easy way to work with your model, an easy solution to what you have in mind could be done by extending the Array type like so:
extension Array where Element == Person {
func retrievePeople(byName name: String) -> People {
return self.filter { $0.name == name }
}
func retrievePeople(byLastName lastname: String) -> People {
return self.filter { $0.lastname == lastname }
}
func retrievePeople(byAge age: String) -> People {
return self.filter { $0.age == age }
}
}
This will allow you to query the entire range of objects by any of the elements and in turn, return the array of matches. If you're certain that there's only one return, you could use the following code to get the first element:
// Let's assume your array of people is stored in this variable
var myPeople: People
if let person = myPeople.retrievePeople(byName: "John").first {
// Do the things you want with this person object here
}
The nice thing about this style of loading/working with data is that it's easy to generate quickly and it will support returning 0 objects, 1 object, and multiple objects. This will also allow you to move the model over to use the features of SwiftUI/Combine (which is what it looks like you're hoping to do above).
In flutter(dart), it is easy to deserialize Json and get a token from it, but when I try to serialize it again, the quotation marks around the keys and values with disappear.
String myJSON = '{"name":{"first":"foo","last":"bar"}, "age":31, "city":"New York"}';
var json = JSON.jsonDecode(myJSON); //_InternalLinkedHashMap
var nameJson = json['name']; //_InternalLinkedHashMap
String nameString = nameJson.toString();
Although the nameJson have all the double quotations, the nameString is
{first: foo, last: bar}
(true answer is {"first": "foo", "last": "bar"})
how to preserve Dart to remove the "s?
When encoding the object back into JSON, you're using .toString(), which does not convert an object to valid JSON. Using jsonEncode fixes the issue.
import 'dart:convert';
void main() {
String myJSON = '{"name":{"first":"foo","last":"bar"}, "age":31, "city":"New York"}';
var json = jsonDecode(myJSON);
var nameJson = json['name'];
String nameString = jsonEncode(nameJson); // jsonEncode != .toString()
print(nameString); // outputs {"first":"foo","last":"bar"}
}
I have a JSON file:
{
"name": "Jens",
"time": "11.45",
"date": "2018:04:17",
"differentTimestamps":[""]
"aWholeLotOfnames":{
"name1": "Karl"
"name2": "pär"
}
How to parse above JSON ? I have checked this tutorial https://www.youtube.com/watch?v=YY3bTxgxWss. One text tutorial to but i don't get how to make a variable that can take a
"nameOfVar"{}
If it's not a dictionary. The tutorial are using a var nameOfVar: [what should be here in this case] for one that nearly looks like it. The thing is though that theirs are starting with a [{ and ends with a }] while mine only starts with a {? i don't know how to solve this?
Creating corresponding Swift data types for JSON is very easy.
A dictionary {} can be decoded into a class / struct where the keys become properties / members.
An array [] can be decoded into an array of the given (decodable) type.
Any value in double quotes is String even "12" or "false".
Numeric floating point values are Double, integer values are Int and true / false is Bool
null is nil
let jsonString = """
{
"name": "Jens",
"time": "11.45",
"date": "2018:04:17",
"differentTimestamps":[""],
"aWholeLotOfnames":{
"name1": "Karl",
"name2": "pär"
}
}
"""
struct Item: Decodable {
let name, time, date: String
let differentTimestamps: [String]
let aWholeLotOfnames: AWholeLotOfnames
}
struct AWholeLotOfnames : Decodable {
let name1, name2 : String
}
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(Item.self, from: data)
print(result)
} catch { print(error) }
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
I am trying to iterate json data in angular2.
If JSON Data is like this
{fileName: "XYZ"}
I am able to iterate using- let data of datas
But If my JSON data key is in string format, how I can iterate in angular2?
{"fileName": "XYZ"}
JSON always have double quoted string keys, so these:
{ fileName: "XYZ" }
{ 'fileName': "XYZ" }
Are not valid jsons, but this is:
{ "fileName": "XYZ" }
Javascript objects don't require the keys to be quoted, and if they are then a single quote can be used:
let a = { fileName: "XYZ" };
let b = { 'fileName': "XYZ" };
let c = { "fileName": "XYZ" };
Here a, b and c are equivalent.
In any case, iterating all of those js object is done in the same way:
for (let key in a) {
console.log(`${ key }: ${ a[key] }`);
}
Object.keys(b).forEach(key => console.log(`${ key }: ${ b[key] }`));