Putting a JSON-String (msg.payload) to a template node

2,969 views
Skip to first unread message

Markus Ulsaß

unread,
Sep 20, 2016, 8:34:49 AM9/20/16
to Node-RED

Hi,

I have a flow which stores the state of a Philips Hue lamp (a JSON string), changes the light and then restores the initial state after a certain delay.

For now I have to put all the key values manually into the template node ("Reset previous state") like this (there are initially more then those values, when requesting the state):

Template-Node ("Reset previous state"):

{
"on" : {{payload.state.on}},
"bri" : "{{payload.state.bri}}",
"hue" : {{payload.state.hue}},
"sat" : {{payload.state.sat}},
"effect" : "{{payload.state.effect}}",
"xy" : [{{payload.state.xy}}],
"ct" : {{payload.state.ct}},
"alert" : "{{payload.state.alert}}",
"colormode" : "{{payload.state.colormode}}"
}



Is it possible to put the whole msg.payload/ JSON-string from the hue state node ("NodeLamp Status") into the template node, without explicitly listing all the key values manually, so that the msg.payload acts like putting a string into the template node?

Best,

Markus

Julian Knight

unread,
Sep 20, 2016, 8:50:37 AM9/20/16
to Node-RED
Well, that's weird, I was recently working through a very similar issue.

The best I've come up with so far is to use JSON.stringify() to convert the JSON to a string. Then you can pass that to a JavaScript that runs in the browser where you JSON.parse() it. Something like:
Function Node:
msg.topic = msg.req.params.id;

var params = msg.req.params;
var query = msg.payload;

msg
.payload = { "params": params, "query": query };

msg
.payload = JSON.stringify(msg.payload);

return msg;

Template:
<!DOCTYPE html>
<html ng-app="ngApp">
<head>
</head>
<body ng-controller="ngCtrl">
   
   
<h1>Topic: {[{topic}]}</h1>
   
<pre>
{[{payload | json }]}
   
</pre>

   
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.12/angular.min.js"></script>
   
<script>
       
var ngApp = angular.module('ngApp', []);
       
        ngApp
.config(function($interpolateProvider) {
            $interpolateProvider
.startSymbol('{[{');
            $interpolateProvider
.endSymbol('}]}');
       
});
       
        ngApp
.controller('ngCtrl', ['$scope', function($scope) {
           
// Need to wrap with TRY in case not valid JSON
            $scope
.payload = JSON.parse(decodeEntities('{{payload}}'));
            $scope
.topic = '{{topic}}';
       
}]);
       
       
function decodeEntities(encodedString) {
           
var textArea = document.createElement('textarea');
            textArea
.innerHTML = encodedString;
           
return textArea.value;
       
}
   
</script>
</body>
</html>

I'm using Angular here but the principles are the same. The input is GET with "/:id" as the URL pattern.

You could use a JSON node to do the convert. Also note that JSON.parse() is very sensitive! Wrap it in a try/catch otherwise it will bomb out when you least want it to.


I'm not especially happy with this approach but it is the best I've been able to come up with so far. Hopefully someone will come up with better.
Reply all
Reply to author
Forward
0 new messages