Writing Functions Guide
Last updated
Last updated
A function component runs JavaScript code on the incoming message and passes it on.
If you are planning to use the function again in other projects, you can create a specific component instead. Learn creating a new component (and functions writing in .js file of its project) in New Component Creation Tutorial.
By convention, an incoming message is an object called msg, and the body of this message contained in the msg.payload property.
Other components may attach other properties to msg. Check their documentation when using.
For your convenience, you may open a wider editor field for a function component:
The default body of a function is return msg;
that passes the incoming message without changes.
If the function returns null
there will be no outcoming message and the flow ends.
The function doesn't have to return the same message object. It can construct a completely new object. For example:
Note: a new message in this instance will lose all the properties of the incoming message. So in many situations, the function should keep the incoming message object when updating its properties. For example, the HTTP In/Response flow requires the msg.req
and msg.res
properties to be preserved end-to-end.
For debuggging purposes use node.warn()
that shows warnings in the sidebar. For example:
See Logging events for more details.
The function component can have multiple outputs. For example, all the messages with "simon" msg.topic will go to the second output here:
The following function will return the incoming message without changes to the first output and its payload length to the second one:
The number of outputs points are set up in the bottom property:
If one of returning messages will be also an array, the corresponding output will show multiple messages.
In the next example, the function converts the input string to an array of words and returns them as multiple messages.
Use a node.send()
function to send messages immediately.
An asynchronous action function before sending a message.
The function component 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.
The function can forbid the runtime to 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 minimize the overhead of sending messages:
To signal the runtime that asynchronous message handling is finished the function should call node.done()
. And the runtime will properly track messages through the system.
In a Setup tab, you can provide code that will run when the component is started.
For example, you can initialize values in a local context that the main function will use:
The Setup function can return a Promise if it needs to complete asynchronous work before the main Function can start processing messages. Any messages that arrive before the Setup function has completed will be queued up, and handled when it is ready.
You can tidy up any outstanding requests and close any connection on flow redeployment in two ways:
add a close event handler:
or add code to the Close tab in the edit dialog.
If you want the component to log some information to console use these functions:
The warn
and error
messages also get sent to the flow editor debug tab.
When the function encounters it returns nothing, but a catch component can log the problem. See the catch component description.
A catch component can be triggered when the function calls node.error()
with the original message as a second argument:
Beside the msg
object, the function can store data in the context store.
There are three predefined variables to access context:
context: the component's local context
flow: the flow context, the variable value is available for other components in the flow
global: the value is accessible in the global (all flows) scope
Note: these variables are the function component way to deal with context. In custom components, it's done differently.
A function can access context in common or asynchronous mode. 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.
Getting a value:
Setting a value:
For example, here the function counts how many times it has been run:
The rule is the same as with multiple outputs: use an array.
Note that in this instance length
will be set to null
due to missing value.
Use an extra callback parameter for the get
and set
functions to access the context store asynchronously.
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:
A function can configure multiple context stores. For example, both a memory and file based store could be used.
To identify the store to use add an optional parameter to the get
/set
context functions.
The global context can be pre-populated with objects when Apps Editor starts. This is defined in the main settings.js file under the functionGlobalContext
property.
For example, learn how to Load additional modules within the function component using global context.
You can add status markers to the function component by calling special functions:
See how it's done in custom components. The parameters and the result are the same.
To use additional modules within the function component they must be loaded in global context. The module must be loaded to the main settings.js file and added to the functionGlobalContext
property.
at which point, the module can be referenced within a function as global.get('externalModule')
.
Modules loaded from your settings file must be installed in the same directory as the settings file. To do this open the project terminal and run:
The following objects are available within the Function node.
node.id
: the id of the Function node - added in 0.19
node.name
: the name of the Function node - added in 0.19
node.log(..)
: log a message
node.warn(..)
: log a warning message
node.error(..)
: log an error message
node.debug(..)
: log a debug message
node.trace(..)
: log a trace message
node.on(..)
: register an event handler
node.status(..)
: update the node status
node.send(..)
: send a message
node.done(..)
: finish with a message
context.get(..)
: get a component-scoped context property
context.set(..)
: set a component-scoped context property
context.keys(..)
: return a list of all node-scoped context property keys
context.flow
: same as flow
context.global
: same as global
flow.get(..)
: get a flow-scoped context property
flow.set(..)
: set a flow-scoped context property
flow.keys(..)
: return a list of all flow-scoped context property keys
global.get(..)
: get a global-scoped context property
global.set(..)
: set a global-scoped context property
global.keys(..)
: return a list of all global-scoped context property keys
APPS.util.cloneMessage(..)
: safely clones a message object so it can be reused
env.get(..)
: get an environment variable
The function component also makes the following modules and functions available:
Buffer
- the Node.js Buffer
module
console
- the Node.js console
module (node.log
is the preferred method of logging)
util
- the Node.js util
module
setTimeout/clearTimeout
- the javascript timeout functions.
setInterval/clearInterval
- the javascript interval functions.
Note: the function component automatically clears any outstanding timeouts or interval timers whenever it is stopped or re-deployed.