🎉 Node-RED 1.0.0-beta.3 released

Regardless of whether it breaks flows downstream, it is a function which you have introduced, and moving it to a more prominent and consistent position, surely will not change whether it breaks flows or not.

We don’t think it should be prominent

I was wondering about this, if a node is disabled, it is clearly visible in the editor.
I think it would make sense to move the option in the "appearance" tab. Then again, I am not bothered by it, doubt I will ever use it.

The appearance tab is about how the node looks in the editor. Disabling the node is not simply changing its appearance - it changes the behaviour of the node.

In 1.0 we are introducing the ability to disable any node. Nodes own their Properties tab in the edit dialog. We cannot insert anything into that tab. This is why the enable button has been added to the footer of the dialog. So what we have done is entirely consistent amongst all nodes.

If anything, I am minded to move the Flow disable button into the footer to match. Then we would be consistent.

5 Likes

The appearance tab is about how the node looks in the editor. Disabling the node is not simply changing its appearance - it changes the behaviour of the node.

I understand. Relabelling 'appearance' to 'properties/settings' could be possible ? I mean, who knows what else the future could bring in terms of 'properties' for a node.

But to quote myself;

Then again, I am not bothered by it, doubt I will ever use it.

Then it wouldn't be a tab about the appearance of the node and the main tab is already called 'Properties'.

We have put some thought into this.

1 Like

All in all, a very useful feature. :+1: I would use it to temporarily disable certain triggers (e.g. mqtt-in) without having to unwire them... and forget to re-add the correct wire later. :see_no_evil:

Although I can't think of any use-cases where I would disable a node mid-flow at the moment.

2 Likes

IMO, consistently is key, especially for new users to node-RED.
From my experience, I'd read that subflows (and other nodes) could be disabled, but didn't see the toggle at the bottom, probably because I was not 'expecting' it to be there.
Also moving the tab flow disable button to the bottom seems logical.

2 Likes

Sorry Julian - forgot to reply on this.

For full consistency, you should set the red-ui-button editor-button css classes on any <a> or <button>.

editor-button is the style for pre-1.0 Node-RED but is being deprecated (but not removed until much later) and red-ui-button is for 1.0 and the longer term.

OK, thanks for that, I will update uibuilder.

Perhaps some some updates to the documentation are needed? Maybe a style guide is needed similar to the one for the help panel?

https://nodered.org/docs/creating-nodes/node-html

Indeed - its on the todo list.

2 Likes

I'm embarrassed but it actually happened to me, I was looking around and could not find where to disable a node, I was looking for it where it is located for tabs. Then I saw it. Once I know it, I see no problems having it where it is

2 Likes

HELP
After much work going from the last pre-1.0 version of Node-Red today I've installed BETA 3. Something imporatnt has stopped working and I cant get to the bottom of it. I'm dimming/switching 2 devices using MQTT. I've put a debug on to watch and it is showing what I'd expect. I use a function node to feed an MQTT node to control the devices - and in the function node I have the following (2 operations)

Firstly on-off

msg.topic="newred/toesp";
var tmp=msg.payload;
if (tmp=="0") msg.payload="{rgbperm:0,0,0,0,128}";
else msg.payload="{rgbperm:0,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",120}";
node.send(msg);

msg.topic="relay_board/toesp";
if (tmp=="0") msg.payload="{rgbperm:15,0,0,0,128}";
else msg.payload="{rgbperm:15,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",60}";
node.send(msg);

And now the colour change function node - same 2 devices..

global.set("deskRed",parseInt(msg.payload.substring(1,3),16));
global.set("deskGreen",parseInt(msg.payload.substring(3,5),16));
global.set("deskBlue",parseInt(msg.payload.substring(5,7),16));

msg.topic="relay_board/toesp";
msg.payload="{rgbperm:15,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",60}";
node.send(msg);
msg.topic="newred/toesp";
msg.payload= "{rgbperm:0,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",120}";
node.send(msg);

As it happens in the first set, I control device newred FIRST, in the second, I control relay_board first.

What is happening since the move to Node-Red 1.0B3 is that in each case only the SECOND node.send is working. Could this be due to the new async nature of Nr 1.0 ? And if so how would I get around this?

On iOS node-red does not seem to load with 1.0.0-beta.3.

Console:
TypeError: undefined is not an object (evaluating 'o.local')

red.min.js context:

 function u(e, t) {
        var i = !1;
        p(e) == t && (i = !0);
        var o = d[e];
        if (t ? $("#" + e).addClass("active") : $("#" + e).removeClass("active"), o) {
            if (o.toggle && "string" == typeof o.toggle && t)
                for (var n in d)
                    if (d.hasOwnProperty(n)) {
                        var a = d[n];
                        a.id != o.id && o.toggle == a.toggle && u(a.id, !1)
                    }
            !i && o.onselect && c(o.id, t)
        }
        o.local || i || RED.settings.set(o.setting || "menu-" + o.id, t)
    }

fails on:
o.local || i || RED.settings.set(o.setting || "menu-" + o.id, t)

I confrm the editor doesn't show in iOS, but the UI does

Yes, it is the same type of problem that I faced. You may look how I fixed it here:

Basically it is about that you need to create new objects when/before you send the message, not using the original msg since it is now being changed "behind the scen" and it is not obvious to realize this at first glance

All users are hereby really encouraged to check their function nodes for this type of thing, otherwise you will experience some nice surprises, hopefully no crashes but not the behavior you expect

Personally I had to go through my huge flow step-by-step, checking and for some function nodes, change the code that was working great before - but not with 1.0

Anyway that is now done and for the rest, I think 1.0 works very well, looks good as well

If you split the function node into two ones, does the first one work then?

@scargill this is the cause of the issue.

You call node.send() on the same message object twice, and as JavaScript passes references around, when you change the topic and payload after the first call to node.send, you are actually still modifying that first message before it has been passed on.

The fix is to use a new object for the second message:

msg.topic="newred/toesp";
var tmp=msg.payload;
if (tmp=="0") msg.payload="{rgbperm:0,0,0,0,128}";
else msg.payload="{rgbperm:0,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",120}";
node.send(msg);

var msg2 = {};
msg2.topic="relay_board/toesp";
if (tmp=="0") msg2.payload="{rgbperm:15,0,0,0,128}";
else msg2.payload="{rgbperm:15,"+ global.get("deskRed") + "," + global.get("deskGreen") + "," + global.get("deskBlue") + ",60}";
node.send(msg2);

and a similar change needed for your other function.


@krambriw et al - today we try to avoid unnecessary cloning of message objects due to the potential overhead that brings. I'm inclined, for the Function node, to automatically clone any message it sends.

That would eliminate this as an issue. The downside is a potential performance hit - particularly functions that already clone themselves, it would be an unnecessary second clone. However, a slight performance drop (that can be resolved by removing the extra clone in the Function code) is far more preferable to changes in behaviour.

2 Likes

Could it be such that node.send is always a clone... but the singular return msg (usually at the end of a function) isn't - so simple functions will be as-is performance wise ?

2 Likes

When I went through my flow and updated it, for function nodes I decided to handle variables in context in a certain way. It would be very interesting to have your opinions on this. Hopefully I do not have to go over it again

So, when storing/updating variables in context from code in function nodes, I have typically this code (sample)

var test = get.global("whatever"); //could be context, flow, global

//
// do some stuff with variable test
//

set.global("whatever", test); 
node.send({ payload:test });

What I selected as principle is to update the variable in context as quickly as possible if I have changed it and always BEFORE doing send. Maybe not so likely to happen but if other parts of your flow could update the same "in the mean time", you might get the wrong end result. At least what I thought, I might be wrong??
Variables in context that is changed just from one node in the flow and only read by others should be safe I think??