JSON array vars in template (HTML)

I know this is not strictly a NR question however I've spent a LOT of time searching without luck. Hopefully this query will help others too. I am not strong at all with HTML I'd be pleased to be pointed somewhere to learn how to specifically do this as well.

I have a JSON array (context.monthly_stats_array) that is updated nightly that has records that look like this:

monthly_stats_array[1] = ({ name: 'Jan', samples: 0, dl_total: 0, dl_avg: 0, sct_total: 0, sct_avg: 0, hct_total: 0, hct_avg: 0});
monthly_stats_array[2] = ({ name: 'Feb', samples: 0, dl_total: 0, dl_avg: 0, sct_total: 0, sct_avg: 0, hct_total: 0, hct_avg: 0 });
monthly_stats_array[3] = ({ name: 'Mar', samples: 0, dl_total: 0, dl_avg: 0, sct_total: 0, sct_avg: 0, hct_total: 0, hct_avg: 0 });

I have created a table in a dashboard template that looks like this (numbers shown are static):

My question is how do I get the JSON array objects (such as "samples" or "dl_avg") into the HTML code of the dashboard template so that I can display them as they get changed?
TIA
st

Here is an example, hope it helps. you can add the style etc.

Can you not just resend the change object?

[{"id":"1f719cb3.b3e5e3","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"2","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[\t   {\t       \"name\":\"Jan\",\t       \"samples\":0,\t       \"dl_total\":$round($random()*10),\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":$round($random()*10)\t   },\t   {\t       \"name\":\"Feb\",\t       \"samples\":0,\t       \"dl_total\":$round($random()*10),\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":0\t   },\t   {\t       \"name\":\"Mar\",\t       \"samples\":0,\t       \"dl_total\":0,\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":0,\t       \"hct_total\":0,\t       \"hct_avg\":0\t   }\t]","payloadType":"jsonata","x":140,"y":1980,"wires":[["4f961563.a5eacc"]]},{"id":"4f961563.a5eacc","type":"ui_template","z":"c791cbc0.84f648","group":"8b5cde76.edd58","name":"","order":9,"width":0,"height":0,"format":"<table>\n    <tbody>\n      <tr ng-repeat=\"(key, value) in msg.payload[0]\">\n        <td>{{key}}</td>\n        <td ng-repeat=\"element in msg.payload\">{{msg.payload[$index][key]}}</td>\n      </tr>\n    </tbody>\n</table>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":300,"y":2080,"wires":[["da13de5e.8621a"]]},{"id":"da13de5e.8621a","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":650,"y":2020,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

My challenge was knowing how to pass the array values into the HTML code in the first place, I think what you have provided will help ... I'll try and let you know.

Thanks so much.

Well, while the solution you provided is some nice code it doesn't help me because:

  • it uses msg.payload as the data source rather then using a context.array in memory
  • it blindly pushes every array element into the output and does not parse out only the ones I require
  • the output is not very elegant

I'm looking to capture particular array elements and then plug them into the table like this:

var data1 = array[12].dl_avg;
var data2 = array{12}.sct_avg

<td> data1 </td>
<td> data2 </td>

1 It is an example, you would need to edit for your use
2 You can change payload to any property you wish including context. Or simplly move context to payload.
3 You can prepare the data the you feed it by removing unwanted properties.
4 Again it is an example you can add css to the table to style. You supplied no html of table for styling(and thats not my job)
5 do some reading

[{"id":"3d042cad.39bbf4","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"some_property_or_context","v":"[\t   {\t       \"name\":\"Jan\",\t       \"samples\":0,\t       \"dl_total\":$round($random()*10),\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":$round($random()*10)\t   },\t   {\t       \"name\":\"Feb\",\t       \"samples\":0,\t       \"dl_total\":$round($random()*10),\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":0\t   },\t   {\t       \"name\":\"Mar\",\t       \"samples\":0,\t       \"dl_total\":0,\t       \"dl_avg\":0,\t       \"sct_total\":0,\t       \"sct_avg\":0,\t       \"hct_total\":0,\t       \"hct_avg\":0\t   }\t]","vt":"jsonata"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":1340,"wires":[["9f7f71b1.37aa08"]]},{"id":"9f7f71b1.37aa08","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$$.some_property_or_context.{\"a _name\": $.name,\t    \"another name\": $.samples, \"a third name\": $.dl_total}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":1380,"wires":[["f0c13732.7afb3"]]},{"id":"f0c13732.7afb3","type":"ui_template","z":"c791cbc0.84f648","group":"8b5cde76.edd58","name":"","order":9,"width":0,"height":0,"format":"<table>\n    <tbody>\n      <tr ng-repeat=\"(key, value) in msg.payload[0]\">\n        <td>{{key}}</td>\n        <td ng-repeat=\"element in msg.payload\">{{msg.payload[$index][key]}}</td>\n      </tr>\n    </tbody>\n</table>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":410,"y":1420,"wires":[["5bee78ba.7559c8"]]},{"id":"5bee78ba.7559c8","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":1380,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

I've spent a LOT of time searching without luck. I am not strong at all with HTML

Over my lifetime I've learned the following programming languages:

fortran
basic
pascal
D-base 3+
Clipper
C (minimally, early 90's)
javascript
arduino (C-ish)
python (to a good degree)

MS-DOS O/S CLI commands
LINUX O/S CLI commands

and of course figured out how to use CSS and moustach.

I'm really NOT interested in fully learning another language, especially HTML (until I have a LOT of use for it) and I do successfully solve the majority of my challenges on my own, only reaching out when stuck.

Forgive me if, for a simple, single task, I chose to look for someone friendly that might help me out.

I showed you how to enter array into table, was it not friendly the help i offered?
I showed you how to edit data using change node and Jsonata. You state you learnt JS, so you could also use that instead.
To display tables with styling you will need to learn html and css, at least for tables.
I offered you some reading that should help.
I never said you need to fully learn another language.
Looking at your topics for help, I see you never let other users know you received/found a solution.

Good luck with you endeavours, Hope you find friendlier help.

Yes, of course. Thank you.

E1cid

I have it solved now however first, allow me to provide some background.

I see now that your initial response was very helpful, but I didn't understand that at the time. This was because I could not comprehend the code you provided ... at all. I looked at it and thought "What is ng, and why would you repeat it? How can you enter (what appeared to be) plain text in that command and have it interpreted into what you seek? And where does $Index just pop up from? How does it loop when it doesn't look anything like a loop command?"

Then I found out about angular (odd name to me, I'm just gonna guess some guy named Angus Angular started it). I researched angular and ng-repeat for some time with my initial read helping some but the explanation and use left me confused. The examples of use (which help me learn best) seemed lacking (for me).

Anyway ...

After reading and re-reading (about angular, different commands and ng-repeat), I started to slowly get it. Then, after significant trial and error, I got it to work (last night). Here is an extract of the code:

  <tr style="height:40px; font-size:20px; text-align:center;">
      <td>Days of Data</td>
      <td <td ng-repeat="elements in msg.payload">{{msg.payload[$index].samples}}</td>
  </tr>
  <tr  style="height:40px; font-size:20px; text-align:center";">
      <td>Available Light</td>
      <td <td ng-repeat="elements in msg.payload">{{msg.payload[$index].dl_avg}}</td>
  </tr>

So I thank you for your assistance, you clearly have command of HTML (and angular). I'd also like to offer (and please read this in the helpful manner I intend it) that "Here is some helpful reading" works better for me. I think that is because too often in forums (that are places where people are supposed to go for assistance, what else is a forum for?), I see the 'club' of "do some reading" used early and alot (perhaps I'm overly sensitive to it) and I'm willing to bet that most (like me) believe we've already tried that.

Again, thanks very much.

1 Like

Cool glad you came to a solution. I would point out that my second example showed you how to change the object property name to ones you wanted to use in the table. so you could of just use an example like below

Html tr and td have been given class elements so css can target them

<style>
table {
    width:100%;
    background-color: white;
    text-align: center;
}
td {
    color: white;
    height:40px;
    font-size:20px; 
}
td[class^=mytablerowstart] {
    background-color: black;
}
td.mytablerowstart0 {
    background-color: white;
}
tr[class^=mytablerow] {
    background-color: blue ;
    font-weight: bold;
}
tr.mytablerow0 {
    background-color: black ;
    font-weight: bold;
}
</style>
<table class="mytable">
    <tbody>
      <tr class="mytablerow{{$index}}" ng-repeat="(key, value) in msg.payload[0]">
        <td class="mytablerowstart{{$index}}">{{key}}</td>
        <td class="mytabledata" ng-repeat="element in msg.payload">{{msg.payload[$index][key]}}</td>
      </tr>
    </tbody>
</table>

The incoming data is then parse with the following JSONata, giving the row titles to

$$.some_property_or_context.{
   "": $.name,
   "Days of Data": $.samples,
   "Available Light": $.dl_avg
}

the flow json

[{"id":"3d042cad.39bbf4","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"some_property_or_context","v":"[\t   {\t       \"name\":\"Jan\",\t       \"samples\":$round($random()*10),\t       \"dl_total\":0,\t       \"dl_avg\":$round($random()*10),\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":$round($random()*10)\t   },\t   {\t       \"name\":\"Feb\",\t       \"samples\":$round($random()*10),\t       \"dl_total\":$round($random()*10),\t       \"dl_avg\":$round($random()*10),\t       \"sct_total\":0,\t       \"sct_avg\":$round($random()*10),\t       \"hct_total\":0,\t       \"hct_avg\":0\t   },\t   {\t       \"name\":\"Mar\",\t       \"samples\":$round($random()*10),\t       \"dl_total\":0,\t       \"dl_avg\":$round($random()*10),\t       \"sct_total\":0,\t       \"sct_avg\":0,\t       \"hct_total\":0,\t       \"hct_avg\":0\t   }\t]","vt":"jsonata"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":1340,"wires":[["9f7f71b1.37aa08"]]},{"id":"9f7f71b1.37aa08","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$$.some_property_or_context.{\t   \"\": $.name,\t   \"Days of Data\": $.samples,\t   \"Available Light\": $.dl_avg\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":1380,"wires":[["f0c13732.7afb3"]]},{"id":"f0c13732.7afb3","type":"ui_template","z":"c791cbc0.84f648","group":"d18ff8e1.9e1118","name":"","order":9,"width":"0","height":"0","format":"<style>\ntable {\n    width:100%;\n    background-color: white;\n    text-align: center;\n}\ntd {\n    color: white;\n    height:40px;\n    font-size:20px; \n}\ntd[class^=mytablerowstart] {\n    background-color: black;\n}\ntd.mytablerowstart0 {\n    background-color: white;\n}\ntr[class^=mytablerow] {\n    background-color: blue ;\n    font-weight: bold;\n}\ntr.mytablerow0 {\n    background-color: black ;\n    font-weight: bold;\n}\n</style>\n<table class=\"mytable\">\n    <tbody>\n      <tr class=\"mytablerow{{$index}}\" ng-repeat=\"(key, value) in msg.payload[0]\">\n        <td class=\"mytablerowstart{{$index}}\">{{key}}</td>\n        <td class=\"mytabledata\" ng-repeat=\"element in msg.payload\">{{msg.payload[$index][key]}}</td>\n      </tr>\n    </tbody>\n</table>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":410,"y":1420,"wires":[["5bee78ba.7559c8"]]},{"id":"5bee78ba.7559c8","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":1380,"wires":[]},{"id":"d18ff8e1.9e1118","type":"ui_group","name":"Default","tab":"27c60ea2.a80aaa","order":1,"disp":true,"width":"12","collapse":false},{"id":"27c60ea2.a80aaa","type":"ui_tab","name":"test","icon":"dashboard","disabled":false,"hidden":false}]

The out come

Apologies if my mannerisms caused you to take offense, that was not my intention. I will leave it there.

You should of asked what $index was and where it came from i would have offered an explanation.

2 Likes

Q: If I have an array where array[0] contains data I wish not included, can ng-repeat be instructed to start at array[1], looking then only at elements [1] to [7] (of [8] elements), just those values?

Excellent. Thanks