0% found this document useful (0 votes)
173 views4 pages

Sending Messages Asynchronously: Since Node-RED 1.0

The document discusses various ways to handle asynchronous operations and messaging in the Node-RED Function node. It covers using node.send() to send messages asynchronously, logging to the console, handling errors, storing and retrieving data from the context stores, and setting node status.

Uploaded by

rshegde
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
173 views4 pages

Sending Messages Asynchronously: Since Node-RED 1.0

The document discusses various ways to handle asynchronous operations and messaging in the Node-RED Function node. It covers using node.send() to send messages asynchronously, logging to the console, handling errors, storing and retrieving data from the context stores, and setting node status.

Uploaded by

rshegde
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Sending messages asynchronously

If the function needs to perform an asynchronous action before sending a message it


cannot return the message at the end of the function.

Instead, it must make use of the node.send() function, passing in the message(s) to
be sent. It takes the same arrangement of messages as that can be returned, as
described in the previous sections.

For example:

doSomeAsyncWork(msg, function(result) {
msg.payload = result;
node.send(msg);
});
return;

Since Node-RED 1.0

The Function node will clone every message object you pass to node.send to ensure
there is no unintended modification of message objects that get reused in the
function. Before Node-RED 1.0, the Function node would not clone the first message
passed to node.send, but would clone the rest.

The Function can request the runtime to not clone the first message passed
to node.send by passing in false as a second argument to the function. It would do
this if the message contains something that is not otherwise cloneable, or for
performance reasons to minimise the overhead of sending messages:

node.send(msg,false);

Logging events
If a node needs to log something to the console, it can use one of the follow
functions:

node.log("Something happened");
node.warn("Something happened you should know about");
node.error("Oh no, something bad happened");

Where the console output appears will depend on how your opearting sustem and
how you start Node-RED. If you start using a command line - that is the console
where logging will appear. If you run as a system service then it may appear in the
system log. If you run under an app like PM2 it will have it’s own way for showing
logs. On a Pi the install script adds a node-red-log command that will display the
log.
The warn and error messages also get sent to the debug tab on the right side of the
flow editor.

For finer grained logging, node.trace() and node.debug() are also available. If there
is no logger configured to capture those levels, they will not be seen.

Handling errors
If the function encounters an error that should halt the current flow, it should return
nothing. To trigger a Catch node on the same tab, the function should
call node.error with the original message as a second argument:

node.error("hit an error", msg);

Storing data
Aside from the msg object, the function can also store data in the context store.

More information about Context within Node-RED is available here.

In the Function node there are three predefined variables that can be used to access
context:

 context - the node’s local context


 flow - the flow scope context
 global - the global scope context

The following examples use flow context, but apply equally well
to context and global.

Note : these predefined variables are a feature of the Function node. If you are creating a custom
node, check the Creating Nodes guide for how to access context.

There are two modes for accessing context; either synchronous or asynchronous.
The built-in context stores provide both modes. Some stores may only provide
asynchronous access and will throw an error if they are accessed synchronously.

To get a value from context:

var myCount = flow.get("count");

To set a value:

flow.set("count", 123);

The following example maintains a count of how many times the function has been
run:

// initialise the counter to 0 if it doesn't exist already


var count = context.get('count')||0;
count += 1;
// store the value back
context.set('count',count);
// make it part of the outgoing msg object
msg.count = count;
return msg;

Get/Set multiple values

Since Node-RED 0.19, it is also possible to get or set multiple values in one go:

// Node-RED 0.19 or later


var values = flow.get(["count", "colour", "temperature"]);
// values[0] is the 'count' value
// values[1] is the 'colour' value
// values[2] is the 'temperature' value
// Node-RED 0.19 or later
flow.set(["count", "colour", "temperature"], [123, "red", "12.5"]);

In this case, any missing values are set to null.

Asynchronous context access

If the context store requires asynchronous access, the get and set functions require
an extra callback parameter.

// Get single value


flow.get("count", function(err, myCount) { ... });

// Get multiple values


flow.get(["count", "colour"], function(err, count, colour) { ... })

// Set single value


flow.set("count", 123, function(err) { ... })

// Set multiple values


flow.set(["count", "colour", [123, "red"], function(err) { ... })

The first argument passed to the callback, err, is only set if an error occurred when
accessing context.

The asynchronous version of the count example becomes:

context.get('count', function(err, count) {


if (err) {
node.error(err, msg);
} else {
// initialise the counter to 0 if it doesn't exist already
count = count || 0;
count += 1;
// store the value back
context.set('count',count, function(err) {
if (err) {
node.error(err, msg);
} else {
// make it part of the outgoing msg object
msg.count = count;
// send the message
node.send(msg);
}
});
}
});

Multiple context stores

With 0.19 it is possible to configure multiple context stores. For example, both
a memory and file based store could be used.

The get/set context functions accept an optional parameter to identify the store to
use.

// Get value - sync


var myCount = flow.get("count", storeName);

// Get value - async


flow.get("count", storeName, function(err, myCount) { ... });

// Set value - sync


flow.set("count", 123, storeName);

// Set value - async


flow.set("count", 123, storeName, function(err) { ... })

Global context

The global context can be pre-populated with objects when Node-RED starts. This is
defined in the main settings.js file under the functionGlobalContext property.

This can be used to load additional modules within the Function node.

Adding Status
The function node can also provide it’s own status decoration in the same way that
other nodes can. To set the status, call the node.status function. For example

node.status({fill:"red",shape:"ring",text:"disconnected"});
node.status({fill:"green",shape:"dot",text:"connected"});
node.status({text:"Just text status"});
node.status({}); // to clear the status

For details of the accepted parameters see the Node Status documentation

Any status updates can then also be caught by the Status node.

You might also like