Accessing data from JSON data files

I would like to pull specific values from two types of JSON files. After reading all of the posts on the subject and trying index, map, etc. I haven’t found a way to get this data out of the JSON files.

Any help would be much appreciated. Thanks y’all!

Example 1: In an array, how can I get the value for a key based on another key/value pair?
For example: rating key for “product_id”: “77777” key

data/reviews.json (from Stamped.io)

[
    {
        "product_id": "77777",
        "rating": 4.8,
    },
    {
        "product_id": "88888",
        "rating": 3.4,
    }
] 

Example 2: How can I get the key in a nested array?
For example price key for a variant id under a given product_id (in other words how can I get the price of the “Hugo Hula Hoop”?)

data/productlist.json (from Shopify)

{
    "products": [
        {
            "id": 1111,
            "title": "Hugo Bobblehead",
            "variants": [
                {
                    "id": 5555555,
                    "product_id": 1111,
                    "price": "1000",
                }
            ],
        {
            "id": 2222,
            "title": "Hugo Hula Hoop",
            "variants": [
                {
                    "id": 6666666,
                    "product_id": 2222,
                    "price": "25",
                }
            ],
        }
    ]
}

What I’ve tried
With help from other posts in the community I found it easy to range through parts of the JSON.

Such as
Range to show the values of one key:

{{ range $.Site.Data.reviews }}
{{ index . “productId” }}
{{ end }}

Range to show the values of multiple keys:

      {{ range $index, $element := $.Site.Data.productlist.products }} 
      (product) id:{{ $element.id }}  
      (product) title:{{ $element.title }}

Fwiw, the documentation on index function and on data templates both show examples where the data files use path to access values. And this user, @kaicastledine, had a similar question which they ended up using file paths to access values.

Merry Christmas :christmas_tree:

Example 1:

{{ $reviews := site.Data.reviews }}
{{ range $reviews }}
  {{ if eq .product_id "77777" }}
    {{ .rating }}
  {{ end }}
{{ end }}

Example 2:

{{ $productlist := site.Data.productlist }}
{{ range $productlist.products }}
  {{ if eq .title "Hugo Hula Hoop" }}
    {{ range .variants }}
      {{ .price }}
    {{ end }}
  {{ end }}
{{ end }}

P.S. the JSON file for this was invalid. Am assuming it should have been:

{
  "products": [
    {
      "id": 1111,
      "title": "Hugo Bobblehead",
      "variants": [
        {
          "id": 5555555,
          "product_id": 1111,
          "price": "1000"
        }
      ]
    },
    {
      "id": 2222,
      "title": "Hugo Hula Hoop",
      "variants": [
        {
          "id": 6666666,
          "product_id": 2222,
          "price": "25"
        }
      ]
    }
  ]
}

1 Like

Oh wow @zwbetz you’re a life saver! I see now what you did with ranging through the file, brilliant! Thank you and Merry Christmas!

Also, fixed the JSON example above for the next person that lands on this thread.

Any idea why this wouldn’t work when using an id and an integer (2222)? Or putting an integer in a string (“2222”).

e.g.

{{ $productlist := site.Data.productlist }}
{{ range $productlist.products }}
  {{ if eq .id 2222 }}
    {{ range .variants }}
      {{ .price }}
    {{ end }}
  {{ end }}
{{ end }}

Hmm not sure. Your code looks fine.

@zwbetz cool, thanks for your help.

Will leave this open for now, maybe someone else out there has an idea on why that won’t work or another solution. Till then I’ll keep trying, will update here if I figure it out.

Hmm, I had thought index might work since that’s a popular response for JSON data questions like this. Perhaps there’s a way to make that work?

{{ (index ((index $.Site.Data.productlist.products 1).variants) 0 ).price }} would generate the price “25” for the Hugo Hula Hoop

Any tips on selecting based on key:value pairs vs positions? e.g. using id:2222 with (variant) id: 6666666 to get price:25.