Accessing the child of a child in a JSON with Handlebars.js - json

I'm having no trouble accessing the initial child of the parent object in a json, however, I cannot seem to figure out what the format for accessing the child of a child is. I'm currently using dot notation as described in the handlebars.js documentation.
My html with handlebars.js implemented (the 'Fees' aren't showing correctly, they show up as [object Object]):
{{#options}}
{{#company_base}}
<div>
<h1>{{name_full}}</h1><b>AM Best Rating</b>: {{ambest_rating}}
<p><b>Type</b>: {{business_type}}</p>
<p><b>Fees</b>:
<ol>
<li><b>Type</b>: {{../..options.fees.type}}</li>
<li><b>Name</b>: {{../..options.fees.name}}</li>
</ol>
</p>
</div>
{{/company_base}}
{{/options}}
My mock JSON:
{
"options": [{
"company_base": {
"business_type": "Life, Accident, and Health",
"established_year": 1998,
"med_supp_state_market_data": [{
"market_share": 0.63490064689900005,
"state": "AK",
"lives": 8041,
"premiums": 14714825,
"claims": 11649263
}, {
"market_share": 0.34445359987700003,
"state": "WY",
"lives": 14916,
"premiums": 30178554,
"claims": 24281001
}],
"underwriting_data": [],
"med_supp_national_market_data": {
"market_share": 0.315510079562,
"state": null,
"lives": 3723184,
"premiums": 8276072271,
"claims": 6436017316
},
"customer_complaint_ratio": 0.0013368044250809999,
"ambest_outlook": "Stable",
"name_full": "Major Health Partners of the Wind",
"ambest_rating": "A",
"parent_company": "aghzfmNzZ2sdfZWRfc3VwcA",
"last_modified": "2017-01-16T12:28:17.591830",
"customer_satisfaction_ratio": 0.83666666666699996,
"default_resources": {
"final-expense-life": {
"e_app_link": ""
},
"medicare-advantage": {
"e_app_link": ""
},
"medicare-supplement": {
"e_app_link": "sdf"
},
"hospital-indemnity": {
"e_app_link": ""
},
"dental": {
"e_app_link": ""
}
},
"key": "assdfsdfVwcA",
"parent_company_base": {
"established_year": 1998,
"code": "707",
"name": "Space Insurance",
"key": "asfdf",
"last_modified": "2016-11-11T16:42:52.240940"
},
"sp_rating": "AA-",
"naic": "79413",
"type": "STOCK",
"name": "Spacewomen Insurance"
},
"has_pdf_app": true,
"rate": {
"quarter": 23841,
"annual": 92964,
"semi_annual": 47682,
"month": 7747
},
"rating_class": "Standard",
"fees": [{
"name": "corgi discount",
"type": "buddy"
}]}
Here is a live example of my issue.

It is not the "child of a child" that you are having trouble accessing, but a sibling property that is of the array type.
There are two problems with your example. First, fees is on the same level as company_base. When you are within the {{#company_base}} {{/company_base}} tags you are within the context of the company_base object, so must step-up one level in order to access its siblings. The correct path would be: {{../fees}}.
Your second issue is that fees is an array. You might want to {{#each}} over this array, but if you want only the first object, then you can access it like: {{fees.0.type}}.
This means that your template should be updated with the following:
<li><b>Type</b>: {{../fees.0.type}}</li>
<li><b>Name</b>: {{../fees.0.name}}</li>
That should do the trick. However, I would like to recommend an alternative way of writing your template. I would eliminate the need to step-up a level to get the fees object by removing the {{#company_base}} {{/company_base}} tags. This will mean that you are at the level of the current object in the options array and you can use dot notation to access its descendant properties. The updated template would look like the following:
{{#each options}}
<div>
<h1>{{company_base.name_full}}</h1>
<b>AM Best Rating</b>: {{company_base.ambest_rating}}
<p><b>Type</b>: {{company_base.business_type}}</p>
<p>
<b>Fees</b>:
<ol>
<li><b>Type</b>: {{fees.0.type}}</li>
<li><b>Name</b>: {{fees.0.name}}</li>
</ol>
</p>
</div>
{{/each}}
Note: I am opting for the more explicit {{#each options}} over {{#options}}.
I have created an example fiddle here.

Related

How to write JSON Path to get particular value based on string filter?

I am new to JSON Path and I am trying to get 'id' corresponding to name='Candy' using JsonPath in below JSON payload.
{
"responsePayload": [
{
"content": {
"id": "101",
"name": "Candy"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/101",
"id": "101"
}
]
},
{
"content": {
"id": "102",
"name": "Chocolate"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/102",
"id": "102"
}
]
}
]
}
For this I tried Jsonpath $.responsePayload[0].content[?(#.name=='Candy')].id but that is not working. I am using https://jsonpath.com/ for testing this JsonPath. Please guide me how I can achieve required result.
You're really close. You need more of the path inside the expression.
$.responsePayload[?(#.content.name=='Candy')].content.id
The [0] you have in your response isolates the first element only, but it sounds like you want to iterate over the whole array in responsePayload. To do that, the filter expression selector [?(...)] must act on that array.
Next, the # represents the current item, and you can build a full path off of it. You can see how that works above.
Finally, the filter expression selector returns the full item when the expression returns true. So you then need to navigate into .content.id again to get the value you're after.

Are JSON nested objects necessary?

I have a question about the way JSON is written. Which is better in terms of usability? I am trying to use a single JSON file for decoding in PHP and Swift, and was wondering which would be the better way for the JSON to be written. Nested objects or no nested objects, essentially.
Option 1
{
"title": "Test",
"image": "image",
"imageCard": "imae2",
"count": 20,
"section": "personal",
"description": "Description",
"color": "#F17B08",
"content": {
"video": true,
"text": true,
"updated": false
},
"homepage": {
"featured": false,
"popular": false,
"new": false
},
"levels": "7-12"
}
]
Option 2
[
{
"title": "Test",
"image": "image",
"imageCard": "imae2",
"count": 20,
"section": "personal",
"description": "Description",
"color": "#F17B08",
"video": true,
"text": true,
"updated": false,
"featured": false,
"popular": false,
"new": false,
"levels": "7-12"
}
]
Thanks!
A JSON structure is often bound to be mapped to an object-oriented class. The closer the JSON structure is from the Model of your program (all the classes, and how each has one or many relationships to others), the easier it will be to deserialize the response from the API.
Now, JSON nesting is necessary just as much as you make associations, compositions and aggregations with your classes.
Let's say you have a Student that has a name, an unique ID and a Teacher which gives many Courses
Having a nested JSON such as:
[
{
"Name":"John Doe",
"ID":"948AFF",
"Teacher":{
"John Nash",
"Classes":[
{...},
{...},
{...}
]
}
},
{
"Name":"William Smooth",
"ID":"123LMLG",
"Teacher":{
"Ulrich Stokes",
"Classes":[
{...},
{...},
{...}
]
}
}
]
Is an intuitive, clean, flexible way to structure the JSON. Because it maps easily to your model. Each element of the array is an instance of a Student which has an instance of Teacher, which has a list of Courses.
Whereas if you had a flat structure like you suggest :
[
{
"Name":"John Doe",
"ID":"948AFF",
"TeacherName":"John Nash",
"ClassesOfTheTeacher":[
{...},
{...},
{...}
]
},
{
"Name":"William Smooth",
"ID":"123LMLG",
"TeacherName":"Ulrich Stokes",
"ClassesOfTheTeacher":[
{...},
{...},
{...}
]
}
]
Forces you to systematically map each field to the attribute of one of your classes. It doesn't stick easily to your model, you have to make some manipulations to map this to your model.
Furthermore, what if suddenly you wanted to have .. 3 Teachers for each student ? Would you end up with TeacherName1, TeacherName2, TeacherName3, and ClassesOfTheTeacher1, ClassesOfTheTeacher2, etc. ? Probably not.
Nested JSON is necessary if you have association/composition/aggregation in your classes.

Google json style guide: How to send single item response?

There is an items node in the specifications which says it is for an array of items, like paging items, youtube video list
What if I have GET request on a single item, how should the response be formatted ?
Just to one item in the array?
items:[item]
https://google.github.io/styleguide/jsoncstyleguide.xml
I don't think #tanmay_vijay's answer is correct or nuanced enough as it seems that single item responses are in arrays in the YouTube example in the docs.
{
"apiVersion": "2.0",
"data": {
"updated": "2010-02-04T19:29:54.001Z",
"totalItems": 6741,
"startIndex": 1,
"itemsPerPage": 1,
"items": [
{
"id": "BGODurRfVv4",
"uploaded": "2009-11-17T20:10:06.000Z",
"updated": "2010-02-04T06:25:57.000Z",
"uploader": "docchat",
"category": "Animals",
"title": "From service dog to SURFice dog",
"description": "Surf dog Ricochets inspirational video ...",
"tags": [
"Surf dog",
"dog surfing",
"dog",
"golden retriever",
],
"thumbnail": {
"default": "https://i.ytimg.com/vi/BGODurRfVv4/default.jpg",
"hqDefault": "https://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg"
},
"player": {
"default": "https://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata",
"mobile": "https://m.youtube.com/details?v=BGODurRfVv4"
},
"content": {
"1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
"5": "https://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata",
"6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
},
"duration": 315,
"rating": 4.96,
"ratingCount": 2043,
"viewCount": 1781691,
"favoriteCount": 3363,
"commentCount": 1007,
"commentsAllowed": true
}
]
}
}
It could however be that it depends on the resource being targeted from the request. This is the way it is in the competing JSONAPI standard.
From JSONAPI standard:
A logical collection of resources MUST be represented as an array, even if it only contains one item or is empty.
You don't need to have items field for showing single item. If you're sure your API is always going to return single object, you can return it as data itself.
{
"data": {
"kind": "user",
"fields": "author,id",
"id": "bart",
"author": "Bart"
}
}
Fields such as data.kind data.fields data.etag data.id data.lang data.updated data.deleted can still be used here.
Source for snippet docs

How to get the parent elements by quering the child elements in the json data.Explanation is given below

I am new to Apigee,I had tried a query to extract the value from the json data child and i need to get the parent element from the json data.
JSON is Here:
{ "Booksstall": [
{ "serialId": "10123456",
"Name": "magic"
"books": [
{ "Order": 3,
"Name": "Supermax"
}
],
"NormalserialIds": [
{"serialId": "1234556",
"Status": "InStock",
"books": [
{"type": "400001623",
"Code": "PATR"
}
]
},
{"serialId": "789101",
"Status": "OutoffStock",
"books": [
{"type": "400001623",
"Code": "NFES"
}
]
}
]
}
]
}
I tried this query in online json validator ,but if I tried same in the Apigee extract variable policy by doing substitution Its not returning me any values.
$.Booksstall[?(#.NormalserialIds[0].serialId=="1234556")].serialId
The above query result is: 10123456.
Please suggest how can I try this.
You can also use Javascript Policy to extract same. It should be simple and straight forward with Javascript Policy.
Cheers,
Anil Sagar

Parsing through JSON .. Gives undefined?

I have a very complex JSON and a snippet of it is below:
var designerJSON=
{
"nodes":
[
{
"NodeDefinition": {
"name": "Start",
"thumbnail": "Start.png",
"icon": "Start.png",
"info": "Entry point ",
"help": "Start point in your workflow.",
"workflow ": "Start",
"category": "Basic",
"ui": [
{
"label": "Entry point",
"category": "Help",
"componet": "label",
"type": "label"
}
]
},
"States": [
{
"start": "node1"
}
]
},.......
]
}
I would like to get the value of "start" in States. But I am stuck in the first step of entering into JSON. When I try
console.log(designerJSON["nodes"]);
I am getting Undefined.
I want the value of start. Wich is designerJSON["nodes"]["States"]["start"].
Can you help.
Thanks in advance
designerJSON["nodes"]["States"]["start"] won't do it.
designerJSON["nodes"] is a list, as is States, so you need to access individual items by index (or iteration).
In the example you have given you need to use this:
designerJSON['nodes'][0]['States'][0]['start']
or this (cleaner IMO):
designerJSON.nodes[0].States[0].start
You have an array in JSON.
instead of
designerJSON["nodes"]["States"]["start"]
use
designerJSON["nodes"][0]["States"][0]["start"]
ps. pay attention on how code is formatted in the topic.
pps. using brackets for accessing properties in js is "bad style" (due to js hint recommendations). better access those via dot, e.g:
designerJSON.nodes[0].States[0].start