How to retrieve values from a deeply nested JSON file

I am self-taught so please forgive my naivety.

My site has data stored in a JSON file that is successfully called using resources.Get and transform.Unmarshal
Here’s the structure of the data

{
    "infoSet": [{
        "info": {
            "dateValue1": "graphValue1",
            "dateValue2": "graphValue2",
            "dateValue3": "graphValue3",
            "dateValue4": "graphValue4",
            "dateValue5": "graphValue5"
        },
        "settings": {
            "settingLabel1" : "settingValue1",
            "settingLabel2" : "settingValue2",
            "settingLabel3" : "settingValue3"
         }
    }]
}

But for the life of me, I cannot retrieve any of the pairs from info or from settings.
I can’t even retrieve the separate maps of info or of settings. Here’s my code:

    {{ $path := "data/graph.json" }} 
    {{ with resources.Get $path }}
        {{ with . | transform.Unmarshal }}
            {{ $variable = . }}
            {{ $infoSetMap := index $variable "infoSet" }}
            {{ $infoMap := index $infoSetMap "info" }}
            {{ $settingsMap := index $variable.infoSet "settings" }}

                    <script>console.log({{ $variable }} '\n * \n' {{ $infoSetMap }} '\n * \n' {{ $infoMap }} '\n * \n' {{ $dateValue }});
                    </script>
                {{ end }}
        {{ end }}
    {{ else }}
    {{ errorf "Unable to get global resource %q" $path }}
    {{ end }}

The console log results are:

  • $variable
    map[infoSet:[map[settings:map[settingLabel:settingValue settingLabel:settingValue settingLabel:settingValue] info:map[dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue]]]]

  • $infoSetMap
    map[settings:map[settingLabel:settingValue settingLabel:settingValue settingLabel:settingValue] info:map[dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue]]]

  • $settingsMap (empty variable)

What am I doing wrong?

You have

  • an object containing a single object named “infoSet”. You access this latter object with {{ $infoSetMap := index $variable "infoSet" }}
  • it contains an Array ([…]) with only one element, which you would access as
    {{ $infoSetArray := index $infoSetMap 0}}
  • And from there, you’d use index $infoSetArray "info" and index $infoSet "settings" to drill further down.

Perhaps a less convoluted JSON structure would help.

2 Likes

Just an option if applicable.

You could store that datafile in your project data folder and use the site.Data method ro access it.

You cojld then omit the resources.Get and unmarshall. See:

1 Like

That’s because the infoSet is an array.

{
  "infoSet": [{
  ]}
}

You can either restructure your data file or replace

{{ $settingsMap := index $variable.infoSet "settings" }}

to

{{ $settingsMap := index (index $variable.infoSet 0) "settings" }}

Thanks, I’ll give that a go.

Does .Site.Data automatically unmarshal the data it retrieves?

The documentation seems to indicate that, I’d say. Did you try it?

Yes. It does. Have a look at the examples on the reference site.Data page above.

Accessing fields ofc will depend on the internal structure of the data file. So the comments from @chrillek and @razon are still valid.

It’s just another way ro deal with.

  • assets: resources.get and unmarshall
  • data: site.Data

Seems so.

I’m just bumbling my way through data retrieval, so I’m not entirely sure how to judge whether json is unmarshalled or not.

But the console shows the same sort of output as outlined above, ie:

map[settings:map[settingLabel:settingValue settingLabel:settingValue settingLabel:settingValue] info:map[dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue dateValue:graphValue]]]

I’ve got to be able to store multiple info objects within a single chart data file.

This has been thoroughly designed. I just didn’t understand how to retrieve them correctly.

Thanks for your help.

This was a huge help. Thank you.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.