Assembling complex multidimensional dictionaries dynamically for JSON in Swift - json

I'm trying to assemble some complex JSON like the following dynamically:
{
"data": {
"attributes": {
"duration_sec": 200
},
"relationships": {
"address": {
"data": {
"id": 1,
"type": "addresses"
}
}
}
},
"included": [
{
"type": "addresses",
"id": null,
"attributes": {
"zip_code": "90210"
}
}
]
}
That is, I have an array of Address structs that I need to loop through to assemble the relationships and included. I would prefer if this were a dictionary, but I could also use SwiftyJSON to just assemble JSON object instead.
When I tried doing this myself, I kept having issues with ambiguity from the compiler, so I honestly don't know how to tackle this problem. I come from dynamic programming languages so am feeling just generally flummoxed by this.

Hard to answer that one without exact compiler error, but usually errors about ambiguity come from the fact that you're trying to create a heterogeneous dictionary and compiler is not able to infer it's type.
In case you want to create a json object like the one above and have use JSON(dictionary:) initializer you should declare a type of dictionary manually as [String: AnyObject]
example:
let exampleDict: [String: AnyObject] = ["one" : 1, "two": "two", "three": [1, 2, 3]]

Related

How to convert reddit posts to list in dart?

I want to get posts from Reddit API. Posts are in "children" node but each object has another object inside.
Can somebody help me write a function that convert this JSON to a list of dart objects?
Here is JSON string.
{
"kind": "Listing",
"data": {
"after": "t3_zzzhq4",
"dist": 2,
"children": [
{
"kind": "t3",
"data": {
"selftext": "blablabla",
"author_fullname": "3xblabla",
"title": "moreblabla",
"created": 1672515982,
"id": "10020p0"
}
},
{
"kind": "t3",
"data": {
"selftext": "blablabla",
"author_fullname": "3xblabla",
"title": "moreblabla",
"created": 1672515982,
"id": "10020p0"
}
}
],
"before": null
}
}
I tried all the tutorials on the topic of complex json parsing, but none of them met my needs. I would know how to parse simple json, but here it is deeply nested JSON, which bothers me a lot, and i cant quite grasp it. Appreciete any help.
Solution:
First go to json to dart and paste JSON string, this generator will make you all classes needed for your JSON.
Then you will need to decode string:
final jsonResponse = json.decode(jsonString);
And then deserialize your JSON like this:
List postslist = list.map((i) => Post.fromJson(i['data'])).toList();
For me, it was crucial i['data']. After adding that, i could deserialize all objects that were living inside that node. Thanks everyone! Hope that someone else this will be helpful! Cheers.

Reading complex json data without iteration

I am working with some data and often the data is nested and i am required to perform some CRUD operations based on the structure of the data i have. For instance i have this json structure
{
"_id": "KnNLkJEhrDsvWedLu",
"createdAt": {
"$date": "2016-10-13T11:24:13.843Z"
},
"services": {
"password": {
"bcrypt": "$2a$30$1/cniPwPNCuwZ/MQDPQkLej..cAATkoGX.qD1TS4iHgf/pwZYE.j."
},
"email": {
"verificationTokens": [
{
"token": "qxe_T9IS7jW7gntpK0Q7UQ35RJ9jO9m2lclnokO3z87",
"address": "drwho#gmail.com",
"when": {
"$date": "2016-10-13T11:24:14.428Z"
}
}
]
},
"resume": {
"loginTokens": []
}
},
"username": "doctorwho",
"emails": [
{
"address": "drwho#gmail.com",
"verified": false
}
],
"persodata": {
"lastlogin": {
"$date": "2016-10-13T11:29:36.816Z"
},
"fname": "Doctor",
"lname": "Who",
"mobile": "+4480000000",
"identity": "1",
"email": "drwho#gmail.com",
"gender": null
}
}
I have several data sets with such complex structure. I need to read the data, edit and also delete. Before i get to iteration, i was wondering how i can read the data without iteration then iterate when i absolutely have to.
What are the rules i should keep in mind when reading such complex json structures to enable me read any complex structure i come across?.
I am currently using javascript but i am looking for rules that apply in other languages as well.
Parsing Json in JavaScript should be easy. http://www.json.org/js.html.
"Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure". Just follow the examples on that page.
If you want to use another language, in Java you could use Jackson or Gson to map those json strings to objects. Then using them becomes easy. Both libraries are annotation based, and wouldn't be difficult to implement.

JSON sometimes array sometimes object

I am consuming an API who's response for a particular field is sometimes and object and sometimes and array of object.
I created a struct to unmarshall the json response and it works great. However, in the instances where the json response has an array of objects, obviously the unmarshalling fails. How can I deal with this situation in Go?
Single Response:
{
"net": {
"comment": {
"line": {
"$": "This space is statically assigned",
"#number": "0"
}
}
}
}
Array Response:
{
"net": {
"comment": {
"line": [
{
"$": "All abuse issues will only be responded to by the Abuse",
"#number": "0"
},
{
"$": "Team through the contact info found on handle ABUSE223-ARIN",
"#number": "1"
}
]
}
}
}
I thought about creating 2 versions of the struct and then somehow determining which instance I got back, but this feels quite wasteful. I have also tried unmarshalling into map[string]instance{} but I got a bit lost and wasn't sure if I was headed down the right path.
Any advice would be appreciated.
Have you tried unmarshall into map[string]interface{}?
type Net struct{
Comment map[string]interface{} `json:"comment"`
}
Then Comment["line"] value is possible array or object.

Siesta: Child resources

I am having difficulties understanding how does Siesta figure out the child of a resource. For example I have the following events resource:
JSON returned by "/events"
{
"success": 1,
"events": [
{
"id": 1,
"type": "meeting",
"eventDate": "2015-08-20",
"notes": "fadsfasfa",
"title": null
},{
"id": 2,
"type": "game",
"eventDate": "2015-08-31",
"notes": "fdsafdf",
"title": null
}
]
}
Sadly, calling "/events/1" for example, does not return the event with id=2. Is there a way to tell Siesta which event has the id=2?
Suppose you have:
let events = myService.resource("/events")
Then you can navigate from the /events resource to the /events/2 resource like this:
let event = events.child("2")
That will give you the same object as if you had asked for myService.resource("/events/2").
To extract that 2 from the JSON, use normal Swift JSON parsing techniques. (Siesta doesn’t apply any special inspection or interpretation to the JSON once it’s parsed.) I recommend using the SwiftyJSON library for easier JSON traversal. For example, it lets you do something like this to extract those event IDs and get the child resources:
let allEventResources =
JSON(events.jsonDict)["events"]
.arrayValue
.flatMap { $0["id"].string }
.map(event.child)

How to do deep sets and gets in Go's map[string]interface{}?

If I have some arbitrary JSON how can I do deep sets and gets on the nested properties using a slice of map keys and/or slice indexes?
For example, in the following excerpt from the JSON API example:
{
"data": [{
"type": "posts",
"id": "1",
"title": "JSON API paints my bikeshed!",
"links": {
"self": "http://example.com/posts/1",
"author": {
"self": "http://example.com/posts/1/links/author",
"related": "http://example.com/posts/1/author",
"linkage": { "type": "people", "id": "9" }
}
}
}]
}
I'd like to get the string "9" located at data.0.links.author.linkage.id using something like:
[]interface{}{"data",0,"links","author","linkage","id"}
I know the ideal way to do this is to create nested structs that map to the JSON object which I do for production code, but sometimes I need to do some quick testing which would be nice to do in Go as well.
You have stretchr/objx that provide a similar approach.
Example use:
document, _ := objx.FromJSON(json)
document.Get("path.to.field[0].you.want").Str()
However, unless you really don't know at all the structure of your JSON input ahead of time, this isn't the preferred way to go in golang…