Iterate array object in liquid template - json

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.

Related

How can I fetch a value from a JSON dictionary?

I am trying to grab the value green from the below JSON data dictionary.
The API endpoint located at http://localhost:9200/api/status give the below data:
{
"name":"prod01",
"uuid":"3430c40-e786-4325-bc48-e0a096956000",
"version":{
"number":"7.17.0",
"build_hash":"60a9838d21b6420bbdb5a4d07099111b74c68ceb",
"build_number":46534,
"build_snapshot":false
},
"status":{
"overall":{
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"title":"Green",
"nickname":"Looking good",
"icon":"success",
"uiColor":"secondary"
},
"statuses":[
{
"id":"core:elasticsearch#7.17.0",
"message":"Elasticsearch is available",
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"icon":"success",
"uiColor":"secondary"
},
{
"id":"core:savedObjects#7.17.0",
"message":"SavedObjects service has completed migrations and is available",
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"icon":"success",
"uiColor":"secondary"
}
]
}
}
And the test.sls file doing the job is:
{% set json_data = salt.cp.get_url('http://localhost:9200/api/status', dest=None) | load_json %}
{% for key, value in json_data.items() %}
{% if value['state'] == 'green' %}
{{ key }}: {{ value }} (found)
{% else %}
{{ key }}: {{ value }}
{% endif %}
{% endfor %}
Executing it, I get the error:
Rendering SLS 'base:svr.salt.dev.test' failed: Jinja variable 'str object' has no attribute 'state'
You are looping on all the key-value pairs of the object json_data, with json_data.items(), so, you do not have a my_dictionary['state'] anymore, what you have is a key which will be state and its value will be green.
This said, your {"state": "green"} is not in the root of your dictionary, so you will never find any key-value pair matching what you need.
What you can do, though is:
{% if load_json.status.overall.state == 'green' -%}
state: {{ load_json.status.overall.nickname }}
{% endif %}
Which would yield:
state: Looking good

JSON parse error on line 5: expecting 'STRING', ' , got "undefined'

I keep getting an error on line 5 and am not sure why, my quotation marks seem good.
{
"tickets": [
{
"id": "{{ticket.id}}",
"additional_tags": [{% for cc in ticket.ccs %}"{{ cc.email }}"{% if forloop.last == false %},{% endif %}{% endfor %}]
}
]
}

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>

Django: how to loop through nested Json object in 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!

Encoding JSON in a GitHub Pages generated file

I'm attempting to create a JSON feed on a GitHub Pages site, and I'm having issues with JSON because I'm not sure how I can properly encode it using Jekyll. Is there an extension or method I can use?
feed: http://iowacodecamp.github.io/sessions.json
source: https://github.com/IowaCodeCamp/iowacodecamp.github.io/blob/master/sessions.json
Note the double quotes in the data.
Your json doesn't validate because of the coma after the last session.
If you don't want a coma after the last session, use forloop liquid object around
{
"sessions": {
"session": [{% for session_hash in site.data.sessions %}{% assign session = session_hash[1] %}
{
"title": {{ session.title | jsonify }},
"description": {{ session.description | jsonify }},
"level": {{ session.level | jsonify }},
"author": {
"name": {{ session.speaker.name | jsonify }},
"slug": {{ session.speaker.slug | jsonify }}
}
}{% if forloop.last == false %}, {% endif %}{% endfor %}
]
}
}
Question : You have multiples sessions in your datas but they are all in the same session array. Do you really need this key ? Maybe you can just do :
{
"sessions": [{% for session in site.data.sessions %}
{{ session[1] | jsonify }}{% if forloop.last == false %}, {% endif %}{% endfor %}
]
}
Which also validates.
I found a list of filters in the documentation: http://jekyllrb.com/docs/templates/
Proper usage is:
{{ session.description | jsonify }}