Updating template one variable at a time

I was unable to find the answer to quite a simple question (I would guess).
Having template with multiple {{variables}}, I would expect to update only ones with passed value but it looks like the whole template is being updated on every incoming message?

Here is simple example:

[{"id":"d9f359da.f5c4a8","type":"inject","z":"45969c2d.16dd0c","name":"","topic":"","payload":"a","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":80,"wires":[["4aa71fcb.043c68"]]},{"id":"bc12f616.498778","type":"inject","z":"45969c2d.16dd0c","name":"","topic":"","payload":"b","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":120,"wires":[["4aa71fcb.043c68"]]},{"id":"4aa71fcb.043c68","type":"function","z":"45969c2d.16dd0c","name":"","func":"if (msg.payload === 'a') {\n    msg.a = 'received: a';\n}\nif (msg.payload === 'b') {\n    msg.b = 'received: b';\n}\n// delete msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":100,"wires":[["e41b8150.b67e28","a2129493.4e3dd8"]]},{"id":"e41b8150.b67e28","type":"ui_template","z":"45969c2d.16dd0c","group":"21e4810e.d4dbe6","name":"","order":0,"width":"6","height":"6","format":"<div>\n    <div>a: {{msg.a}}</div>\n    <div>b: {{msg.b}}</div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":540,"y":100,"wires":[[]]},{"id":"a2129493.4e3dd8","type":"debug","z":"45969c2d.16dd0c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":530,"y":140,"wires":[]},{"id":"21e4810e.d4dbe6","type":"ui_group","z":"","name":"Test","tab":"fa232f71.167e7","order":1,"disp":true,"width":"6"},{"id":"fa232f71.167e7","type":"ui_tab","z":"","name":"Test","icon":"dashboard","order":3}]

having displayed a: "{{msg.a}}" -> a: "foo" and sending msg.b = 'bar', a is removed from the display resulting in a: "".
I have quite big SVG drawing in my template. So in order to update one part of it I have to do one of the following?:

  • store every variable in some context and always pass all variables in msg to the template
  • resign from using simple {{msg.variable}} and use ugly scope.$watch('msg', function(msg) {//search element and update its content

Both approaches looks much less pretty than just simple updating {{msg.variable}} by sending msg.variable = 'new value'; to the template.

Put a Join node on the input to the template, set to generate key/value pairs using msg.topic as the key, then the data in the latest messages on both inputs will be available every time.

2 Likes

The whole template will be updated with the msg properties. In you example, when msg.a is undefined then

<div>
    <div>a: {{msg.a}}</div>
    <div>b: {{msg.b}}</div>
</div>

will result :

r-01

This seems to be a reasonable and expected behavior, in my opinion.
I have updated msg.a to undefined, so I expect this reflected in the dashboard.
The bottom line is that it is necessary to add the required logic in the flow to craft the msg properties in the proper way. This is in line with what Colin suggested in his previous post (use a join node).

1 Like

Thanks guys for the reply. Ok, updating template even when no matching variable is passed seems reasonable as you described it. Thanks for the hint about join via key/value. That node gathers and stores all information passed to it. I'll work on persistence so it's all good after deploy but for now it looks nice and working.

1 Like

Continuing the discussion from Updating template one variable at a time:

Hello There,
I have a similar finding and looking for some advice.

I have a simple grouping of textboxes that I need to have a color background applied to it that indicates the status of a "channel" of barcode scanner results. Good running condition is Green background with Black text. A warning would be Yellow background, Black text. and an alarm being Red with White text. etc.. I have at most 18 channels to display on 3 different Groups of these items on the same tab. I noticed that if I use some of the key variables more than once, the resulting color does not obey the code. I did resolve this by updating the offending text box template with an alternate key name and that seemed to solve the problem.
For instance alarm, I couldn't name it "alarm2", It behaved the same way, confusing me.. But if I named it "Alarm" changing the first character to a capital "A", it then would cooperate and the key was unique.

<div layout="row" layout-align="space-between">
<p ng-bind-html="msg.PICA1"></p>
<p id="msg" ng-bind-html="msg.payload" ng-class="{
    blank: msg.topic == '',
    warn: msg.topic == 'warn',
    Alarm: msg.topic == 'alarm',
    good: msg.topic == 'OK',
    stop: msg.topic == 'STOP'
    }">
 </p>
 </div>
    <style>
        #msg * {
            outline-color:black;
            outline-style: inset;
            text-align:center;
            width:220px;
            height: 27px;
            display:table-cell;
            color: #000;    
            background-color: grey;
            vertical-align: middle;
        }
        .warn {
            outline-color:black;
            outline-style: inset;
            text-align:center;
            width:220px;
            height: 27px;
            font-size: 16px;
            color: #000;    
            background-color: yellow; 
            vertical-align: middle;
        }
        .good {
            outline-color:black;
            outline-style: inset;
            text-align: center;
            width: 220px;
            height: 27px;
            font-size: 16px;
            color: #000;    
            background-color: limegreen; 
            vertical-align: middle;
        }
        .blank {
            outline-color:black;
            outline-style: inset;
            text-align:center;
            width:220px;
            height: 27px;
            font-size: 16px;
            color: #000;    
            background-color: limegreen; 
            vertical-align: middle;
        }
        .Alarm {
            outline-color:black;
            outline-style: inset;
            text-align:center;
            width:220px;
            height: 27px;
            font-size: 16px;
            color: #FFF;
            background-color: #F00;    
            vertical-align: middle;
        }
        .stop {
            outline-color:black;
            outline-style: inset;
            text-align:center;
            width:220px;
            height: 27px;
            font-size: 16px;
            color: #000;
            background-color: white;    
            vertical-align: middle;
        }
    </style>

As far as I can interpret, the scope is on the dashboard, not node. Each individual template is not confined in scope to the data flow, but open to the dashboard tab scope, maybe the group??? . Is that true? Can someone explain?

Thanks,
Kyle

Hi Kyle, you are using a closed thread to ask something that seems not to relate to the original question of the post. I believe you would have more chances of having your issue supported if you start a brand new thread. It would help too if you post the full flow or at least a simplified flow that could allow us to do a real testing with your data. Apparently you could benefit from the capabilities of CSS to style the output the way you want. Just need more information to try to help you.

Thanks,
I was just trying to conserve new threads... and look for some information rather than getting a new thread going on old topics.

I guess it is a matter of understanding CSS and what is actually going on behind the scenes. To some degree I look up information on w3, but sometimes it does not really explain the relationship to the dashboard vs. a web page CSS. I think I have what I need so far because I used a new prefix on my textboxes value keys when I copied the code to a new template. That seems to have eliminated dashboard key ambiguity.

Thanks.
We can leave this thread...

Just to answer that. Yes, NR Dashboard uses old AngularJS and not modern Angular unfortunately, so it don't separate CSS per component/node. All your CSS from one node spills out to the whole Dashboard. I use unique parent class to make sure my css won't alter anything else.