The Function node allows JavaScript code to be run against the messages that are passed in and then return zero or more messages to continue the flow.
The message is passed in as an object called msg. By convention it will
have a msg.payload property containing the body of the message.
Other nodes may attach their own properties to the message, and they should be described in their documentation.
The code entered into the Function node represents the body of the function. The most simple function simply returns the message exactly as-is:
return msg;If the function returns null, then no message is passed on and the flow ends.
The returned message object does not need to be same object as was passed in; the function can construct a completely new object before returning it. For example:
var newMsg = { payload: msg.payload.length };
return newMsg;msg.req and
msg.res properties to be preserved end-to-end. In general, function
nodes should return the message object they were passed having made any
changes to its properties.The function edit dialog allows the number of outputs to be changed. If there is more than one output, an array of messages can be returned by the function to send to the outputs.
This makes it easy to write a function that sends the message to different
outputs depending on some condition. For example, this function would send
anything on topic banana to the second output rather than the first:
if (msg.topic === "banana") {
return [ null, msg ];
} else {
return [ msg, null ];
}The following example passes the original message as-is on the first output and a message containing the payload length is passed to the second output:
var newMsg = { payload: msg.payload.length };
return [msg, newMsg];A function can return multiple messages on an output by returning an array of messages within the returned array. When multiple messages are returned for an output, subsequent nodes will receive the messages one at a time in the order they were returned.
In the following example, msg1, msg2, msg3 will be sent to the first output.
msg4 will be sent to the second output.
var msg1 = { payload:"first out of output 1" };
var msg2 = { payload:"second out of output 1" };
var msg3 = { payload:"third out of output 1" };
var msg4 = { payload:"only message from output 2" };
return [ [ msg1, msg2, msg3 ], msg4 ];The following example splits the received payload into individual words and returns a message for each of the words.
var outputMsgs = [];
var words = msg.payload.split(" ");
for (var w in words) {
outputMsgs.push({payload:words[w]});
}
return [ outputMsgs ];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. For example:
doSomeAsyncWork(msg, function(result) {
node.send({payload:result});
});
return;If you do use asynchronous callback code in your functions then you may need to
tidy up any outstanding requests, or close any connections, whenever the flow gets
re-deployed. You can do this by adding a close event handler.
node.on('close', function() {
// tidy up any async code here - shutdown connections and so on.
});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");The warn and error messages also get sent to the flow editor debug tab.
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);Aside from the msg object, the function can also store data between invocations
within it’s context object.
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;By default, the context data is not persisted across restarts of Node-RED.
context was to access it directly:
var count = context.count;This method is still supported, but deprecated in favour of the
context.get/context.set
functions. This is in anticipation of being able to persist the context data in a future release.
In Node-RED 0.13 or later, just as the context object is local to the node,
there is also a flow-level context that is shared by all nodes, not just Function
nodes, on a given tab. It is accessed via the flow object:
var count = flow.get('count')||0;There is also a global context available that is shared by, and accessible to all nodes. For example to make the variable foo available globally across the canvas:
global.set("foo","bar"); // this is now available to other nodesAnd can then be read using .get
var myfoo = global.get("foo"); // this should now be "bar"The global context can also be pre-populated with objects when Node-RED starts. This is defined in the main settings.js file under the functionGlobalContext property.
For example, the built-in os module can be made available to, all functions:
functionGlobalContext: {
osModule:require('os')
}at which point, the module can be referenced within a function as
global.get('osModule').
If any external module is “required”, it must be installed manually in the user directory via npm.
cd ~/.node-red
npm i name_of_3rd_party_module_to_be_required
context:
context.global.foo = "bar"; var osModule = context.global.osModule;This method is still supported, but deprecated in favour of the
global.get/global.set
functions. This is in anticipation of being able to persist the context data in a future release.
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 statusFor details of the accepted parameters see the Node Status documentation
Any status updates can then also be caught by the Status node (available in Node-RED v0.12+).
The Function node also makes the following modules and functions available:
Buffer - the Node.js Buffer moduleconsole - the Node.js console module (node.log is the preferred method of logging)util - the Node.js util modulesetTimeout/clearTimeout - the javascript timeout functions.setInterval/clearInterval - the javascript interval functions.Note: the function node automatically clears any outstanding timeouts or interval timers whenever it is stopped or re-deployed.
Node-RED is a visual wiring tool for the Internet of Things.
A project of the JS Foundation.