0

flow image

NOTE: per @hardillb answer, I fixed the above flow and posted the right one below. Thanks in advance for any help. I am a beginner in HTML and have to use it in Node-RED. I have a simple flow (shown in the image link above). I inject a message with sample line graph points in payload. I want to receive the message in an HTML script in a template node, which then renders the received msg.payload data on a line graph on the browser. The HTML script works fine if I generate random graph from inside the script, but I am failing to get the script to receive msg.payload. I tried something similar to How to send msg.payload from function node to template node

The HTML script in waveform HTML is below. I indicated TODO what I tried and didn't work.

<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {

//define line graph options for CanvasJS line graph
var options =  {
 exportEnabled: true,
 animationEnabled: true,
 animationDuration: 200,
 theme: "light2",
 title :{
  text: "Simple Line Chart"
 },
 axisY: {
  includeZero: false
 },
 data: [{
  type: "spline",
  indexLabelFontSize: 16,
  dataPoints: []  //this will be loaded with "y" values from msg.payload
 }]
};

//TODO not working ---------------------
//load WaveData from msg.payload 
var WaveData = [];
var createWaveData = function () {
    WaveData = {{{payload}}};   //TODO fix, not working
    //WaveData = [1, 2, 3, 4, 5, 4, 3, 2, 1]; //debug code, works fine, sample data is plotted on graph
}
//--------------------------------------

var updateChart = function (cnt) {
 createWaveData();
 options.data[0].dataPoints = [];
 for (var j = 0; j < cnt; j++) { 
  yVal = WaveData[j];
  options.data[0].dataPoints.push({y: yVal});
 }
 (new CanvasJS.Chart("chartContainer", options)).render();

};

var updateInterval = 2000;
setInterval(function(){ updateChart(WaveData.length) }, updateInterval); 

}

</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width:100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script> 
</body>
</html>

This is the CORRECT flow per @hardillb answer.

The corrected flow per hardillb answer

hardillb
  • 54,545
  • 11
  • 67
  • 105
user13160236
  • 1
  • 1
  • 5
  • 1
    No, the inject node still serves no useful purpose here, remove it entirely. Also edit the question to show what's in the function node – hardillb Apr 07 '20 at 06:24

1 Answers1

1

Node-RED nodes only act on one message at a time.

The http-in node will produce a message, which will be updated by the template node and then returned by the http-out node. The http nodes must act as a pair, with one input message leading directly to a http response to the browser that made the request.

The template node holds no state, it just renders the template with data from the incoming messages.

So having the inject node will not do anything useful, because after the template node renders any information in the message the http-out node will discard it because it did not come from a http-in node.

You need to include a node between the http-in node and the template node which will update the msg.payload with your data. This can be either a change node or a function node. Both can be used to take a context variable and update the msg from the be http-in node.

Then in the template node you need something like

var waveData = {{payload}};

You may need 3 sets of curly braces, to stop the array getting HTML escaped, check the info sidebar for the template node

Edit:

Actually having been back and looked at the doc for the template node again you don't need the function node to use a context variable in the template node. Meaning that the following should work.

var waveData = {{flow.waveData}}

enter image description here

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • Thanks for the answer. I updated the flow per your answer and I can get the msg now. However, I still did not figure out how to load msg.payload into WaveData[] – user13160236 Apr 06 '20 at 23:13
  • Thanks for the answer. I updated the flow per your answer and I can get the msg now. However, I still did not figure out how to load msg.payload into WaveData[] – user13160236 Apr 06 '20 at 23:19
  • is there is reason why to use flow.waveData instead of flow.get('waveData') ? – user13160236 Apr 07 '20 at 19:05
  • Because it won't work and it's not what is in the doc. See the bottom of the template's info sidebar. – hardillb Apr 07 '20 at 19:17