Overview
The function node executes JavaScript code to process messages.
The most powerful and flexible node for data transformation, calculations, and custom logic.
Access flow/global context, use external libraries, and create complex workflows.
JS
JavaScript
Multi
Outputs
Context
Storage
Async
Support
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| func | string | "return msg;" | JavaScript code to execute |
| outputs | number | 1 | Number of output ports |
| initialize | string | "" | Code run once on startup |
| finalize | string | "" | Code run on shutdown |
Available Objects
msg
The message object being processed
msg.payload // Main data
msg.topic // Message topic
msg._msgid // Unique ID node
Node-specific functions
node.send(msg) // Send message
node.warn("...") // Log warning
node.error("...") // Log error context
Node-level persistent storage
context.get("key")
context.set("key", value) flow / global
Flow and global context storage
flow.get("key")
global.set("key", value) Example: Data Transformation
Convert Celsius to Fahrenheit with validation.
// Convert temperature and add metadata
var celsius = msg.payload.temperature;
if (typeof celsius !== 'number' || isNaN(celsius)) {
node.warn("Invalid temperature value");
return null; // Drop message
}
msg.payload = {
celsius: celsius,
fahrenheit: (celsius * 9/5) + 32,
kelvin: celsius + 273.15,
timestamp: Date.now(),
status: celsius > 30 ? "high" : celsius < 10 ? "low" : "normal"
};
return msg; Example: Multiple Outputs (Router)
Route messages to different outputs based on conditions.
// Route by severity (3 outputs configured)
var value = msg.payload.value;
var threshold = msg.payload.threshold || 50;
if (value > threshold * 1.5) {
// Critical - Output 1
msg.severity = "critical";
return [msg, null, null];
} else if (value > threshold) {
// Warning - Output 2
msg.severity = "warning";
return [null, msg, null];
} else {
// Normal - Output 3
msg.severity = "normal";
return [null, null, msg];
} Example: Using Context Storage
Calculate rolling average using flow context.
// Calculate rolling average (last 10 values)
var readings = flow.get("readings") || [];
readings.push(msg.payload);
// Keep only last 10
if (readings.length > 10) {
readings.shift();
}
flow.set("readings", readings);
// Calculate average
var sum = readings.reduce((a, b) => a + b, 0);
var average = sum / readings.length;
msg.payload = {
current: msg.payload,
average: average.toFixed(2),
samples: readings.length,
min: Math.min(...readings),
max: Math.max(...readings)
};
return msg; Example: Async Operations
Handle asynchronous operations with node.send().
// Async with setTimeout (simulating delay)
setTimeout(function() {
msg.payload = "Delayed message: " + msg.payload;
node.send(msg);
}, 1000);
// Important: return nothing for async
return null;
// Alternative: Using promises
// const result = await someAsyncFunction();
// msg.payload = result;
// return msg; Best Practices
Do
- • Return
nullto drop messages - • Use
node.warn()for debugging - • Validate input data types
- • Keep functions focused and simple
- • Use context for state between messages
Don't
- • Modify
msgand return it multiple times - • Use blocking operations (use async instead)
- • Store large data in global context
- • Ignore error handling
- • Use
console.log(use node.warn)