Knowing when a node is done - new node API

If you have created your own nodes, there's a new callback function signature being introduced in Node-RED 1.0 that will allow the runtime to keep better track of when nodes are done with a message.

This is what drives the new 'Complete' node that is also being introduced. You can already see this in action with the current beta release, and there's no time like the present to start updating your nodes to the new API. The following blog post explains what's changing and how nodes can adopt the new API in an entirely backward compatible way.

The 'creating nodes' docs will be updated nearer the release.

3 Likes

Nick, is there a way to target node-red versions for custom nodes?

For example, if I used a feature not present in pre V1 is there a way to limit installation of my node to avoid unnecessary negative feedback?

Edit ...
Apologies if this is something I've missed in the documentation.

1 Like

Yes in the node-red section of package.json you can specify eg

    "node-red": {
        "version": ">=0.18.0",
        "nodes": {
            "serialport": "25-serial.js"
        }
    },
2 Likes

Don't forget to target node.js if you need to as well. All of mine are now targetting node.js v8.16 as a minimum and Node-RED v0.18.

1 Like

Great new feature.

It would nice not to have to test for the existence of done each time it is used. Would it be possible to do something like

send = send || node.send;
done = done || done0;

function done0(text,msg){
    if (arguments.length > 0) {
        return node.error(text,msg)
    } else {return}
}

Or have I missed a bunch of edge cases?

1 Like

This is similar to what I've done except that I've just included a dummy function for done unless I reach a situation where I need to call it with an error object which seems to be fairly rare in my nodes.

if I setup:

        this.on('input', function (msg, send, done) { // eslint-disable-line complexity
            // If this is pre-1.0, 'send' will be undefined, so fallback to node.send
            send = send || node.send;
            // ...
            send(msg);
            done();
        }

In Node-red 1.0 it is working fine, in Node-Red 0.20.8 get the error:

26 Sep 08:34:08 - [info] [within-time-switch:39ac9572.49ebba] TypeError: this.metric is not a function
    at Node.send (C:\GFApps\nodejs\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:216:10)
    at withinTimeSwitchNode.<anonymous> (U:\Development\github\node-red-contrib-sun-position\nodes\within-time-switch.js:299:25)
    at emitOne (events.js:116:13)
    at withinTimeSwitchNode.emit (events.js:211:7)
    at withinTimeSwitchNode.Node.receive (C:\GFApps\nodejs\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:237:14)
    at InjectNode.Node.send (C:\GFApps\nodejs\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:159:22)
    at InjectNode.<anonymous> (C:\GFApps\nodejs\node_modules\node-red\node_modules\@node-red\nodes\core\core\20-inject.js:78:26)
    at emitOne (events.js:116:13)
    at InjectNode.emit (events.js:211:7)
    at InjectNode.Node.receive (C:\GFApps\nodejs\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:237:14)
26 Sep 08:34:08 - [error] [within-time-switch:39ac9572.49ebba] internal error within-time-switch:this.metric is not a function

For starters, you have called done() which doesn't exist pre-v1. See the notes just above your post. So you need to fix that first and see what impact it has.

@Hypnos thanks for reporting. Yes, you've found a problem with the recommended approach for migrating to the new api whilst keeping it backward compatible. I'm now curious as to why I didn't spot that in my testing.

The proper workaround is:

send = send || function() { node.send.apply(node,arguments) };
1 Like

Yes, you are right, in my real code I have done = done || ... as well. The error occurs on the send( line.

Thank you!

Ah, well that makes a decision for me - time for me to move some of my code to a new common library that will be pushed to npm independently so I only have to change it in one place.

1 Like

I look forward to that, as this thread and the blog post has made difficult reading for me... especially the example given in the blog section Backwards compatibility.

I'm sure it say's more about my abilities, than the expression of the author.

2 Likes