Django: how to loop through nested Json object in html - html

I am new to json, and I have a nested json object called jresult in django view.py. I passed this object to html and I wanna display it in html.
in view.py:
return render(request,'home.html', {'jresult': jresult})
jresult:
{
"company": "xxx",
"address": "xxx",
"ceo": "xxx,
"employee": {
"Emily": {
"id": "xxx",
"gender": "xxx"
},
"Tom": {
"id": "xxx",
"gender": "xxx"
},
"Alex": {
"id": "xxx",
"gender": "xxx"
},
},
}
So far I can only loop through the employee's name and display them in the html page: Emily, Tom and Alex by the following html code:
{% for obj in jresult.employee %}
<p>{{obj}}</p>
{% endfor %}
how can I access the id and gender as well, I have tried
{% for obj in jresult.employee %}
<p>{{obj}}</p>
{% for item in jresult.employee.obj.gender %}
<p>{{item}}</p>
{% endfor %}
{% endfor %}
but it doesn't work.
Any helps will be appreciated.

Take a look at this (similar request) or (if it don't work) you can implement your own filter to transform the json in the desired form
Edit:
Basically you can try
{{ jresult['employee'] }}
because as cited in the first link, you have dictionaries in the json

JSON is a nested structure so you should be able to access attributes of relative objects using a simple dot notation. You must have the employee field as an array, not an object, if you want to iterate through them like so:
Try this:
{% for obj in jresult.employee %}
<p>{{obj}}</p>
<p>{{obj.id}}</p>
<p>{{obj.gender}}</p>
{% endfor %}

You can do {{ jresult['employee']['Emily'] }} and then use dot notation to print the remaining
{{ jresult['employee']['Emily'].gender }}
That should print the gender if I am not mistaken. However this is not maintainable as it requires you to know the names of each key before printing.
Django templates should allow you to do something like this, as json should be treated as python dictionary.
{% for employee_key, employee_value in jresult.employee %}
<p>{{employee_key}}:{{employee_value}}</p>
{% endfor %}
Reference: https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#for
Asides from this - I would probably just write a serializer/transformer to change this data into template readable before sending it to the front-end.
Hope this helps!

Related

Shopify Looping Over JSON Metafield Arrays

For some reason, I can't access an array within a JSON metafield.. I've tried the other StackOverflow answers, and I'm using value, etc. but just can't figure it out, here's my metafield:
product.metafields.artist.releases
with a value of:
{
  "releases": [
   { 
"id": 0,
    "releaseName": "lofi 1",
    "coverArt": "",
    "releaseLink": “”
},
 { 
"id": 1,
    "releaseName": " lofi 2",
    "coverArt": "",
    "releaseLink": “”
}
]}
(which formats to: "{\"releases\":[{\"id\":0,\"releaseName\":\"lofi 1\",\"coverArt\":\"\",\"releaseLink\":“”},{\"id\":1,\"releaseName\":\"lofi 2\",\"coverArt\":\"google.com\",\"releaseLink\":“”}]}")
and I'm using this in the product.custom.liquid:
{{ product.metafields.artist.releases.value }}
{% assign releases = product.metafields.artist.releases.value %}
{% for release in releases.releases %}
{{ release.releaseName }}
{% endfor %}
the first one shows up fine, and if I assign it and do {{ releases }} it shows up fine as well so I know the assignment is working, but I can't forloop over it (mind you that the first object in the JSON is also called releases (I've also tried renaming it all to unique names just in case and that didn't help))
For some reason when it is a multidimensional JSON array it acts weird. There is a simple fix for it, just add (-) at the end of your assigned variable:
{%- assign releases = product.metafields.artist.releases.value -%}
{% for release in releases.releases %}
{{ release.releaseName }}
{%- endfor -%}
Hope it solves your problem like it did mine!
Liquid is not going to work on JSON like this. If you want to iterate through an array of JSON objects, use Javascript.
As lov2code points out by adding (-) it trims the output for any unnecessary white space, which enables you to traverse the JSON array.

How to handle json dictionary in Liquid templates?

I am rather new to Liquid templates, but I don't seem to find a way to loop through a dictionary in json and access the different values.
Disclaimer: I am using the Shopify Liquid Preview extension for VSCode.
Input json file:
The input file contains two properties: CustomerId and Transactions, which is the 'dictionary' property, containing a list of KeyValuePairs. I want to loop through the Transactions collection and output the TransactionValue properties.
{
"CustomerId": 13,
"Transactions": {
"1": {
"Id": "1",
"TransactionValue": 1000
},
"2": {
"Id": "2",
"TransactionValue": 207.47
}
}
}
Expected output:
<h1>Customer 13</h1>
<ul>
<li>1000</li>
<li>207.47</li>
</ul>
Current Attempt
I can easily loop the collection, but then it's not clear to me on how I can access the actual properties of the current transaction. None of the following work. When just outputting the variable, it gets printed like this: 1,[object Object]
<ul>
{% for trx in Transactions %}
<li>{{trx}}</li>
<li>{{trx.Key}}</li>
<li>{{trx.Value}}</li>
<li>{{trx.Object}}</li>
{% endfor %}
</ul>
I don't really have control over the input json, so I was hoping to find a good way on making this work as is.
Thank you
In most Liquid flavors it should be possible to reference an object field by name like this:
{{ Transactions["1"].TransactionValue }}
Then it is a matter of getting all known transactionIds from somewhere. If they're not available as an array, then the dirty solution could be to parse raw incoming JSON, e.g. like that:
{% assign transactionIds = Transactions | split: "\"Id\": \"" %}
<ul>
{% for id in transactionIds %}
{% if id[0] != "{" %}
{% assign realId = id | split: "\"" | first %}
<li>
{{ Transactions[realId].TransactionValue }}
</li>
{% endif %}
{% endfor %}
</ul>

Iterate array object in liquid template

I have a problem when my Liquid template iterate in array object. I want to transform an input json into another output json.
It is my Liquid Template:
{% assign clientList = Clients.value %}
{
"value": [
{% for client in clientList %}
{
"ACCOUNTNUM": "{{client.ACCOUNTNUM}}",
"EMAIL": "{{client.EMAIL}}",
"NAME": "{{client.NAME}}",
"PHONE": "{{client.PHONE}}",
"VATNUM": "{{client.VATNUM}}",
"RECID": "{{client.RECID}}",
"CANALID": "{{client.CANALID}}",
"CANALDESC": "{{client.CANALDESC}}"
}
{% if forloop.Last == false %}
,
{% endif %}
{% endfor %}
]
}
It is an input json example:
{
"Clients":{
"value":[
{
"#odata.etag":"",
"ItemInternalId":"3a93f2aa-dd77-4297-88c4-13241343321",
"ACCOUNTNUM":"01",
"EMAIL":"info#example.es",
"LANGUAGEID":"es",
"NAME":"Lili S.A.",
"PHONE":"943444666",
"VATNUM":"A01",
"DATAAREAID":"tr2",
"RECID":1412,
"DATAAREAID_x0023_2":"tr2",
"DATAAREAID_x0023_3":"tr2",
"CANALID":"C0010",
"CANALDESC":"Group gg"
},
{
"#odata.etag":"",
"ItemInternalId":"3a23f2aa-dd77-4297-88c4-13241343321",
"ACCOUNTNUM":"02",
"EMAIL":"info#example.es",
"LANGUAGEID":"es",
"NAME":"Lili2 S.A.",
"PHONE":"943444656",
"VATNUM":"A02",
"DATAAREAID":"tr2",
"RECID":1412,
"DATAAREAID_x0023_2":"tr2",
"DATAAREAID_x0023_3":"tr2",
"CANALID":"C0011",
"CANALDESC":"Group2 gg"
}
]
}
}
When I have launched my Logic App I got this error:
{\"StatusCode\":400,\"ErrorCode\":18,\"Details\":null,\"Message\":\"An error occurred while converting the transformed value to JSON. The transformed value is not a valid JSON. 'After parsing a value an unexpected character was encountered: :. Path 'print1', line 5, position 11.'\"
According to some test, it should be caused by the part shown as below in your liquid:
{% if forloop.Last == false %}
,
{% endif %}
I removed this part and the liquid map works fine, here I post my liquid map below for your reference:
{
"value": [
{% for client in content.Clients.value %}
{
"ACCOUNTNUM": "{{client.ACCOUNTNUM}}",
"EMAIL": "{{client.EMAIL}}",
"NAME": "{{client.NAME}}",
"PHONE": "{{client.PHONE}}",
"VATNUM": "{{client.VATNUM}}",
"RECID": "{{client.RECID}}",
"CANALID": "{{client.CANALID}}",
"CANALDESC": "{{client.CANALDESC}}"
},
{% endfor %}
]
}
Don't worry about the last "," because the "Transform JSON to JSON" action will deal with it. In the output of the "Transform JSON to JSON" action, it will not show an extra "," at the end of the json.

Pass an Array to an include to loop over

I have an include that can have >1 buttons depending on what is passed in.
Currently I have the following in the include:
{% if include.buttons %}
{% for button in include.buttons %}
<a class="{{ button.classes }}" href="{{ button.url }}">{{ button.title }}</a>
{% endfor %}
{% endif %}
Then I am trying to pass in the following data:
{% assign buttons = '[{ "title": "button 1", "url": "https://#", "classes": "btn btn-transparent" }, { "title": "button 2", "url": "https://#", "classes": "btn btn-primary" }]' %}
{% include header.html
buttons=buttons
%}
What I can't work out is how to pass the data correctly to the include so that I may loop through it.
The problem is the assignment of the data as a array. In liquid you can not directly initialize arrays. A workaround is to play with split.
However, using jekyll you can provide arrays via data files. Simply put your buttons in a file, say _data\buttons.yml with:
postXX:
- button1:
- title: "button 1"
- url: "https://#"
- classes: "btn btn-transparent"
- button2:
- title: "button 2"
- url: "https://#"
- classes: "btn btn-primary"
Now you could put a reference in the yaml-header of your post/page like:
---
your other yaml options....
buttons: postXX
---
Finally, assign the buttons and include them as you did in your code.
{% assign buttons = site.data.buttons[page.buttons] %}
{% include header.html
buttons=buttons
%}
With Liquid, you can't create an array with a literal expression like {% assign myArray = ["one","two","three"] %}.
You can only :
create empty one : {% assign emptyArray = "" | split: "" %}
create one from string : {% assign myArray = "one two three" | split: " " %}
You can then manipulate your array :
add an element to array : push or shift (jekyll specific filters)
remove an element from array : pop or unshift (jekyll specific filters)
merge two arrays with concat
and so on ...
So, your array can only come from a liquid array manipulation or some datas contained in configuration, data file or page front matter.

JSON not replacing variables

I'm using Twig PatternLab.
I got a small issue with JSON and a Twig for loop.
Atom 00-h3-black.twig:
<h3 class="A-ChevronBlack">{{ text.chevron }}</h3>
Molecule 00-mastertile.twig:
<div class="M-DMasterTile">
<div class="image"></div>
<div class="content">
{% include "atoms-h3-black" %}
</div>
</div>
Organisms 00-default2.twig:
{% for post in default2 %}
{% include "molecules-mastertile" %}
{% endfor %}
And JSON inside Organism folder 00-default2.json
{
"default2" : [
{
"text" : {
"chevron" : "How to build a campfire",
"body" : "This is the body copy"
}
},
{
"text" : {
"chevron":"Lorem Ipsum",
"body" : "This is the body copy"
}
}
]
}
My expectation is for the "default2" to loop twice because I've got an array with 2 items in the JSON and push the JSON content. If I take the variables out of the JSON array it shows the changes(but obviously duplicated).
What am I doing wrong here?
I appreciate your help
include uses global scope and there is no variable text in it. Use include with syntax to pass variable into inner scope.
Your Organisms 00-default2.twig should look like this:
{% for post in default2 %}
{% include "molecules-mastertile" with {'text': post.text} %}
{% endfor %}