Working with JSON Data And JavaScript Objects in Node-Red

JSON=NodeJSON is popular format for encoding data sent over the Internet, and also stored in files.

In computing, JavaScript Object Notation (JSON) is an open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types (or any other serializable value). –wiki





In this tutorial we will look at how you encode and decode JSON data and how you extract values from JSON message payloads.

Encoding and Decoding JSON Data

You can encode and decode JSON data using the JavaScript functions JSON.stringify() and JSON.parse() or the JSON Node.

Encoding JSON Data

Creating a JSON string from a JavaScript object

var s=JSON.stringify(JavascriptObject);

Decoding JSON Data

Creating a JavaScript object from a JSON string

var o=JSON.parse(JSONString);

The JSON node located under the functions category is capable of converting between a JSON string and JavaScript object and vice versa.

JSON=Node-Properties

Receiving JSON Data

The first thing you need to do when you receive JSON data is to convert it into a JavaScript object.

Once you have a JavaScript object you can work on the data.

The two approaches using the JSON node and the JSON.parse() command are illustrated below:

working-with-JSON-data

Is it JSON Data or a JavaScript Object?

One of the most common problems that I’ve seen is trying to extract data from a JSON string thinking that it was a JavaScript object.

In Node-red if you pass the data into the debug node then it will show you the data and tell you the data type.

JSON data is a string and is surrounded in quotes as shown below.

debug-node-display-JSON

Extracting Values from a JSON String Payload

A Common requirement is to extract a particular value or values from the incoming JSON data in the message payload.

To do that the first thing we must do is to convert the JSON string into a JavaScript object.

Once we have a JavaScript object we can extract individual values using the key in dot format or quotes notation.

The following screen shot illustrates the process, using the command line ,along with some common problems that you might encounter like:

SyntaxError: Unexpected token o in JSON at position 1

JSON-Javascript-example

Note: The node command line doesn’t require var declaration or ; to terminate the line. You will need them in the script in the function node.

JavaScript Object Notes:

Generally a JavaScript object key doesn’t need quotes. In the example above we used.

var o={temp:20,humidity:50};

and not

var o={"temp":20,"humidity":50};

However both are valid.

There are various rules on whether or not quotes are needed (see here). However it is usually best to use quotes to avoid confusion.

When accessing a value in a JavaScript Object you can use:

var value=o.temp;

or

var value= o["temp"];

The bracketed option will always work the dot notation will work depending on the key name.

The following screen shot illustrates assigning values to objects using the node command line.

Javascript-Object-examplre

To access the data we encounter the same problems without quotes.

Access-data_Javascript-object

Using Variables as Keys

Using a variables as an object key is a common requirement.

Again you find that you are required to use the bracketed option and not the dot notation.

var light="light1";
var o={};
o[light]="on";

Again We illustrate using the node command line.

Variables-javascript-objects

Manually Entering JSON Data

When testing it is often necessary to create test data.

It is relatively easy to hand code Simple JSON data, however for more complex data I would recommend using the node command line to create the JSON Data from a JavaScript object.

In JSON all string values must be in quotes. See here

var s={temp:10}; //create JavaScript object
var  s='{"temp":10}';
var s="{\"temp\":10}";

as shown below:

manual-Json-data

Entering JSON Data into the Node-Red Inject Node

This is very common in testing.

Select the JSON option and enter the data using quotes around strings.

The JSON edit will show you if you have entered an invalid format.

json-edito-node-red

Using the Mosquitto Publish Tool With JSON

With the mosquitto_pub tool you will need to escape the quotes and enclose it in quotes.E.G.

mosquitto_pub -h localhost -t test -m "{\"v1\/lights\":1}"

Notice also how I needed to delimit the forward slash in the key name.

Workbook

If you would like some worked examples and exercises then try my workbook.

Video -Working With JSON Data in Node Red

Demo Flow

Summary

The JSON data format is used extensively and node-red provides the JSON node to convert JSON to JavaScript Object and a JavaScript Object to JSON.

In addition function nodes can use the JSON.parse and JSON.stringify functions.

Being familiar with JSON and concerting between formats and extracting data from JSON is vital skill in IOT applications.

Related videos:

I have created a number of videos on JSON that you might find useful:



Related Tutorials:

Click to rate this post!
[Total: 2 Average: 4]

14 comments

  1. Can u please tell me how do I get api json data into function node using javascript and also count the number of times the particular word occurred plz help me.

  2. I have a node that is outputting the following :
    {“currentTemp”:24.5,”targetValue”:20,”isUserCustom”:false,”currentSchedule”:{“temp”:20,”day”:”Saturday”,”time”:”08:00″},”nextSchedule”:{“temp”:22,”day”:”Saturday”,”time”:”20:00″},”currentHeaterStatus”:”off”}

    I would like to only send the currentHeaterStatus part of this message to an mqtt topic, and ignore the rest.
    Is there a way to do that?
    Thanks

    1. assuming it is in the payload
      let payload=msg.payload
      let currentHeaterStatus=payload.nextSchedule.currentHeaterStatus;

      should do it
      Rgds
      Steve

  3. Hi !
    I have a file (.txt) that has a series of JSON formatted entries (rows) which looks like this:
    {
    “name”: “surf-JohnDoe”,
    “fname”: “John”,
    “lname”: “Doe”,
    “replyto”: 1930,
    “chatId”: 1435856758,
    “messageId”: 1934,
    “spot”: “kvsk”,
    “start”: “2021-02-03T08:25:49.736Z”,
    “stop”: “2021-02-03T08:26:02.703Z”,
    “sail”: “2”,
    “rating”: “9”
    }
    {
    “name”: “surf-JaneDoe”,
    “fname”: “Jane”,
    “lname”: “Doe”,
    “replyto”: 1956,
    “chatId”: -402899591,
    “messageId”: 1960,
    “spot”: “gh”,
    “start”: “2021-03-09T18:25:36.710Z”,
    “stop”: “2021-03-09T18:25:48.891Z”,
    “sail”: “1”,
    “rating”: “7”
    }

    What is the best way to get this into a key/value array ? I tried reading entire file into a string and then sending that tring into JSON node but I am struggling and think there is an easier option…this should be really easy since everything is formatted for key/value …

    Any ideas are very welcome

    kind rgds
    Orjan

    1. It looks like it is already a jSON file so pass it from the file node to a JSON node and then a debug node and you should see an object.
      If not what do you see?

  4. Srry for the stupid Question. Its time to go to sleep.
    Solution is try catch
    try{
    msg.payload = JSON.parse(msg.payload);
    }
    catch(e)
    {
    return null;
    }-

    insert facepalm here. goodnight

  5. Hi there,
    I have came up with a new problem.
    I got a serial conenction from a esp32 to a rasp where node red is running on.
    Throu the Serial Port come Json and not Jason Data but i Only care for the Json.
    By using the json flow debugging get horrible cause soe many
    “Unexpected token m in JSON at position 0” exceptions.
    So I need something like a “tryparse” to cast the msg into a json and if it failed i dont pass the msg.

    Do you guys have a smart lien of code for this problem?

  6. Hi Steve,
    What are the following used for? I don’t understand why it is in the code.
    data[“sensor_id] = “0001”;
    data[“sensor_type”] = “power”;
    Thanks,
    Scott

    1. Not sure where you are getting the code from but it looks to me like I’m creating sample data to use.
      Rgds
      Steve

  7. this is very close to what i am trying to do, but cannot seem to get it to work using function nodes in node red.
    I have a javascript object as a global variable, and want to change a single value in the key/value pair. If i try to change just one variable and update with the global.set(‘myvarname’,mynewvar); it clears the entire ‘myvarname’ object and replaces it with only the one key/value pair that i changed, all others are deleted. Is there another javascript command to use other than .set?
    below is sample flow of trying to change one variable (c10.seconds) of the c10 object.
    Thanks for the tutorials, they are largely very helpful….
    [{“id”:”f97e0be.271ebf8″,”type”:”tab”,”label”:”Flow 3″,”disabled”:false,”info”:””},{“id”:”edccee99.4f5bd”,”type”:”inject”,”z”:”f97e0be.271ebf8″,”name”:”0″,”topic”:””,”payload”:””,”payloadType”:”date”,”repeat”:””,”crontab”:””,”once”:true,”onceDelay”:0.1,”x”:270,”y”:140,”wires”:[[“508d6166.5baf4”]]},{“id”:”508d6166.5baf4″,”type”:”function”,”z”:”f97e0be.271ebf8″,”name”:”set global variables”,”func”:”c10 = {};\nc10.onoff = 1;\nc10.seconds = 60; \nglobal.set(‘c10’,c10);\nreturn [msg];”,”outputs”:1,”noerr”:0,”x”:310,”y”:200,”wires”:[[“399ff698.7be93a”]]},{“id”:”af2911c2.d63c9″,”type”:”function”,”z”:”f97e0be.271ebf8″,”name”:”change 1 global var”,”func”:”c10 = {};\nc10.seconds = 80;\nglobal.set(‘c10’,c10);\nreturn [msg];\n\n”,”outputs”:1,”noerr”:0,”x”:310,”y”:340,”wires”:[[“6f52f6f2.a53258”]]},{“id”:”399ff698.7be93a”,”type”:”function”,”z”:”f97e0be.271ebf8″,”name”:”read global var”,”func”:”c10 = global.get(‘c10’);\nout1 = {};\nout1 = {payload: c10, topic:msg.topic, };\nreturn [out1];”,”outputs”:1,”noerr”:0,”x”:300,”y”:260,”wires”:[[“bef79cb4.490d7″,”af2911c2.d63c9”]]},{“id”:”bef79cb4.490d7″,”type”:”debug”,”z”:”f97e0be.271ebf8″,”name”:”before variable change”,”active”:true,”tosidebar”:true,”console”:false,”tostatus”:false,”complete”:”true”,”targetType”:”full”,”x”:580,”y”:260,”wires”:[]},{“id”:”e1b37585.949f58″,”type”:”debug”,”z”:”f97e0be.271ebf8″,”name”:”after variable change”,”active”:true,”tosidebar”:true,”console”:false,”tostatus”:false,”complete”:”true”,”targetType”:”full”,”x”:580,”y”:400,”wires”:[]},{“id”:”6f52f6f2.a53258″,”type”:”function”,”z”:”f97e0be.271ebf8″,”name”:”read global var”,”func”:”c10 = global.get(‘c10’);\nout1 = {};\nout1 = {payload: c10, topic:msg.topic, };\nreturn [out1];”,”outputs”:1,”noerr”:0,”x”:300,”y”:400,”wires”:[[“e1b37585.949f58”]]}]

    1. Hi
      In you function change global variable use

      var c10 =global.get(“c10”);
      c10.seconds = 81;
      global.set(‘c10’,c10);
      return [msg];
      in the function read global use

      c10 = global.get(‘c10’);
      return [c10];

      You could combine the two function nodes and use

      var c10 =global.get(“c10”);
      c10.seconds = 81;
      global.set(‘c10’,c10);
      msg=c10;
      return [msg];

      rgds
      steve

      1. Wow, that should have been obvious to me, you simply need to get the object before you modify the object. dhuuu.
        You might consider making that point a little more clear in your tutorial, i at least didn’t see it.

        Since you have to ‘get’ the entire object to modify a key value pair, from a speed of code execution standpoint is this the best way to access and modify data or is it better to use an individual global(or flow) variable for a key/value pair. In my case i will probably have 1 object with about 100 key/value pairs and access or modify them 2 to 4 times per flow/execution?

        a cup of coffee is coming your way.

Leave a Reply

Your email address will not be published. Required fields are marked *