template node

2,934 views
Skip to first unread message

matt vorwald

unread,
Aug 3, 2016, 4:12:31 PM8/3/16
to Node-RED
i'm trying to grasp mustache syntax,  Just set up a little test flow and i keep falling on my a$$.  can someone take a peak at this and give me a nudge of guidance?

[{"id":"29358637.fad68a","type":"debug","z":"e8566d8f.d29e2","name":"","active":true,"console":"false","complete":"false","x":1796.6666666666665,"y":631.1111111111111,"wires":[]},{"id":"3ff35c3c.2279e4","type":"template","z":"e8566d8f.d29e2","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Hello {{name}}. Today is {{date}}","x":1638,"y":565,"wires":[["29358637.fad68a"]]},{"id":"2a7275c2.f8b47a","type":"inject","z":"e8566d8f.d29e2","name":"","topic":"","payload":"{   name: \"Fred\",   date: \"Monday\"   payload: ... }","payloadType":"str","repeat":"","crontab":"","once":false,"x":1574,"y":391,"wires":[["3ff35c3c.2279e4"]]}]

Nicholas O'Leary

unread,
Aug 3, 2016, 4:19:44 PM8/3/16
to Node-RED Mailing List
Hi,

in a mustache template {{name}} will get replaced by the value of msg.name and {{date}} by the value of msg.data

In this flow, you are setting msg.payload to a string that you've copied from the help text - but it is just a string - you are not setting msg.name and msg.date themselves which is what the template looks for.

Start simple. Change your inject node to set msg.payload to "World". Then change your template to:
   Hello {{payload}}!

When you inject, you'll get "Hello World!" as the value of msg.payload has been inserted.


Next, add a Change node that sets msg.name to "matt" and msg.date to "Wed 3 Aug" and set the template back to:
  Hello {{name}}. Today is {{date}}

Now when you inject, you will get the properly rendered message - Hello matt. Today is Wed 3 Aug


Nick







On 3 August 2016 at 21:12, matt vorwald <mvor...@webtechiowa.com> wrote:
i'm trying to grasp mustache syntax,  Just set up a little test flow and i keep falling on my a$$.  can someone take a peak at this and give me a nudge of guidance?

[{"id":"29358637.fad68a","type":"debug","z":"e8566d8f.d29e2","name":"","active":true,"console":"false","complete":"false","x":1796.6666666666665,"y":631.1111111111111,"wires":[]},{"id":"3ff35c3c.2279e4","type":"template","z":"e8566d8f.d29e2","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Hello {{name}}. Today is {{date}}","x":1638,"y":565,"wires":[["29358637.fad68a"]]},{"id":"2a7275c2.f8b47a","type":"inject","z":"e8566d8f.d29e2","name":"","topic":"","payload":"{   name: \"Fred\",   date: \"Monday\"   payload: ... }","payloadType":"str","repeat":"","crontab":"","once":false,"x":1574,"y":391,"wires":[["3ff35c3c.2279e4"]]}]

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
For more options, visit https://groups.google.com/d/optout.

matt vorwald

unread,
Aug 3, 2016, 4:59:49 PM8/3/16
to Node-RED
ok, that makes sense, i'm dumping 10 lines out of mysql and i want to use the template node of UI to display them.  Do i use the change node to parse each element into a individual msg.payload?  or is there a better way?  Here are two lines of my data that the my sql node is returning.  

[ { "Time": "2016-08-03T16:08:17.000Z", "Moisture": 16.1, "Grain_Temp": 118, "Ave_Moist": 16.2, "Machine_On": 0, "Target_Temp": 180, "Actual_Temp": 178, "Air_Temp": 82.9, "Humdity": 80, "Static_Pressure": 0 }, { "Time": "2016-08-02T21:04:01.000Z", "Moisture": 16.1, "Grain_Temp": 118, "Ave_Moist": 16.2, "Machine_On": 0, "Target_Temp": 180, "Actual_Temp": 178, "Air_Temp": 0, "Humdity": 0, "Static_Pressure": 0 } ]

So i'm thinking one big parser that will take and split on the "," and then return each of these as msg.time1 and msg.moist1 and msg.graintemp1 ......  msg.time10

then i can go into the template and build the code of {{time1}} "  " {{moist}}

or is there a node to better handle mysql data?

Many Thanks!

Nicholas O'Leary

unread,
Aug 3, 2016, 5:26:13 PM8/3/16
to Node-RED Mailing List
With the core template node, with mustache, you could do something like:

<table>
{{#payload}}
   <tr><td>{{Time}}</td><td>{{Moisture}}</td><td>{{Grain_Temp}}</td></tr>
{{/payload}}
</table>

This uses mustache's ability to loop over the elements of an array - in this instance, it expects msg.payload to be an array, and for each element in that array, it renders an html table row. Injecting the example data you've shared, this would produce:

<table>
    <tr><td>2016-08-03T16:08:17.000Z</td><td>16.1</td><td>118</td></tr>
    <tr><td>2016-08-02T21:04:01.000Z</td><td>16.1</td><td>118</td></tr>
</table>


So with that generated, you ought to be able to pass that to the ui_template node.... but that's where I get stuck.

I have to admit I've not done much with the ui_template node (rather than the core node-red template node).
The ui_template node doesn't use mustache syntax - it uses angular markup. Have to admit, it is one of the things I didn't like about contrib-ui - it ignored what we do else where in node-red and used it's own thing that looks very similar but is very different.

What I can't figure out is how to pass in html to the ui_template node and have it render as html, rather than display the raw html. Hopefully someone who has used it more than I have will be able to advise...

Nick


Dave C-J

unread,
Aug 4, 2016, 4:40:16 AM8/4/16
to node...@googlegroups.com
To render the msg.payload as-is html... set the ui-template to be
<div ng-bind-html="msg.payload"></div>
I will add this to the sidebar docs as it's going to be a common use-case

matt vorwald

unread,
Aug 4, 2016, 10:36:35 AM8/4/16
to Node-RED
That is pretty slick, thanks for the nudge so just to recap use the {{#}} to start reading the array and the {{}} to pick up each element.  

Can you think of a way to use the moment node to tame down that time stamp?  All i really need is hours and minutes.  I like having it all in the database, but for my UI i don't need the rest.

Oh, and thanks Dave, that ng-bind-html works great!

Nicholas O'Leary

unread,
Aug 4, 2016, 10:43:26 AM8/4/16
to Node-RED Mailing List
Matt, no need to jump to moment. Your dates are well formatted strings, so you just need a bit of string manipulation.
For a simple instance of your date/time string:

    var s = "2016-08-03T16:08:17.000Z"
    var t = s.substring(11,16)

would do it - this extracts the 11th-16th characters of the string which are your hours:mins


As your data is in an array and you want to apply it to every element, you can add a Function node before the Template node that does something like:

    msg.payload.forEach(function(o) { o.Time = o.Time.substring(11,16)})
    return msg;

To explain: .forEach() is a function on arrays that will call the provided Function once for each element in the array. All we do is just replace the Time property of the element with the substring version.


Nick



To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

matt vorwald

unread,
Aug 4, 2016, 11:37:52 AM8/4/16
to Node-RED
i'm getting this error  "TypeError: o.Time.substring is not a function"???

if i replace the o.Time.substring(11,16) with a simple 1 it works great!  All my times are replaced w/ 1's!

so i'm thinking it's a syntax thing??

matt vorwald

unread,
Aug 4, 2016, 3:38:55 PM8/4/16
to Node-RED
this doesn't work either....

for (var i = 0, len = msg.payload.length; i < len; i++)
{ i.Time = i.Time.substring(11,16);}

return msg;

gives me this error
TypeError: Cannot read property 'substring' of undefined

Nicholas O'Leary

unread,
Aug 4, 2016, 5:40:25 PM8/4/16
to Node-RED Mailing List
Matt,

you've not quite got that for loop right. 'i' will be the position (count) into the array, not the array element itself.

for (var i = 0, len = msg.payload.length; i < len; i++) {
  var element = msg.payload[i];
  element.Time = element.Time.substring(11,16);
}

But the error you got with my original suggestion implies that what is being passed into this function isn't the array of objects I thought it was.

Try this one: it will print to the console (where you're running node-red) some debug that reports the type of individual elements in the payload, just to confirm they are what you think they are:

for (var i = 0, len = msg.payload.length; i < len; i++) {
  var element = msg.payload[i];
  console.log(typeof element, element);
  element.Time = element.Time.substring(11,16);
}



To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

matt vorwald

unread,
Aug 5, 2016, 8:49:48 AM8/5/16
to Node-RED
when i toss your code in i get this in the debug for that function node

TypeError: element.Time.substring is not a function 

I thinking it doesn't like substring.  Because i made this loop to change some other values and it works Perfectly.  I've also tried substring on a different element and got the same error 

TypeError: o.Moisture.substring is not a function

just for full disclosure here is all the code that is currently in that function node


 
//change 1's and 0's to ON and OFF
msg.payload.forEach(function(o){    
    if (o.Machine_On === 1) o.Machine_On = "ON ";
    if (o.Machine_On === 0) o.Machine_On = "OFF";
});

msg.payload.forEach(function(o)
{ o.Moisture = o.Moisture.substring(1,2);  });    
for (var i = 0, len = msg.payload.length; i < len; i++) {
    var element = msg.payload[i];
    console.log(typeof element, element);
    element.Time = element.Time.substring(11,16);
}
  return msg;

Julian Knight

unread,
Aug 9, 2016, 5:18:45 PM8/9/16
to Node-RED
Although you certainly don't NEED to, you could certainly use it if you want to avoid a function node - depends on your proclivities on maintaining code vs configuration.

Here is an example flow based on your example input:

[{"id":"925c9bba.8f9d48","type":"moment","z":"462586cc.55d938","name":"","topic":"","input":"payload.time","inputType":"msg","inTz":"Europe/London","adjAmount":0,"adjType":"days","adjDir":"add","format":"HH:mm","locale":"en_GB","output":"","outputType":"msg","outTz":"Europe/London","x":460,"y":1160,"wires":[["ae2ae65a.94de38"]]},{"id":"2cba53d0.5cad2c","type":"inject","z":"462586cc.55d938","name":"","topic":"","payload":"[ { \"Time\": \"2016-08-03T16:08:17.000Z\", \"Moisture\": 16.1, \"Grain_Temp\": 118, \"Ave_Moist\": 16.2, \"Machine_On\": 0, \"Target_Temp\": 180, \"Actual_Temp\": 178, \"Air_Temp\": 82.9, \"Humdity\": 80, \"Static_Pressure\": 0 }, { \"Time\": \"2016-08-02T21:04:01.000Z\", \"Moisture\": 16.1, \"Grain_Temp\": 118, \"Ave_Moist\": 16.2, \"Machine_On\": 0, \"Target_Temp\": 180, \"Actual_Temp\": 178, \"Air_Temp\": 0, \"Humdity\": 0, \"Static_Pressure\": 0 } ]","payloadType":"json","repeat":"","crontab":"","once":false,"x":270,"y":1160,"wires":[["925c9bba.8f9d48"]]},{"id":"ae2ae65a.94de38","type":"debug","z":"462586cc.55d938","name":"","active":true,"console":"false","complete":"false","x":670,"y":1160,"wires":[]}]
Reply all
Reply to author
Forward
0 new messages