Search code examples
jsonhandlebars.js

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


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.


Solution

  • 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.