Upgrading Nodes specifically my own

I wonder if someone can advise. I've just made an update recently to node-red-contrib-bigtimer. While it works well (some new fields) - existing users will get the warning they need to fill in a value for the new fields. I figured as these are inputs, if I put a value "0" in there, existing users of the node would not be harrassed by this but I was wrong..

hard to guess on so little info but maybe it depends how you are testing - as "", 0 , false and undefined can all evaluate falsey in Javascript.

So I added

input="0"

to the new fields and STILL the existing node users (i.e. me) when upgrading the node, get faced with a warning that they need to complete entering info into the node. The node shows greyed out "0" without the quotes in the new fields but the user still has to put something in there manually - usually 0. I'd have thought me presetting an input value would prevent that.

depends how you are triggering the warning.

So, the user updates the node Bigtimer and a red triangle appears next to the node which means they now need to fill in the zeros for the fields I've added which are supposed to default to value zero. Not a game changer but for example I have dozens of BigTimers in my installation.

Just because the node has the new field doesn't mean the users old flow has it... so the validator will fail. (hence red triangle) - so you probably need to create a custom validator that accepts "nothing" or a number - and then in the js code treat nothing as 0. (assuming you really need to validate it)

1 Like

I hate to admit this but after spending 2 hours on this, I could not come up with a working solution so I simply took the validators out.

Pete

The bit I really don't follow is... in the html form, you can enter value="0"... hich SHOULD put a default value of 0 in the input but cleraly doesn't.

I think you have to add that to the "default" section of the .js file, if you want that behavior, don't you?

Hi Pete, I think I ran into something similar. One of the things I did was to change the field debug and received "... workspace contains some nodes that are not properly configured ... ". I had changed debug from a text input to a checkbox. The JSON for the flow still contained the "debug": "0" I had originally set it to (text field was a quick hack). Now I have it set as: to ndebug: { value: false } and left the original debug field in place but unused. I no longer see the complaint. This is not a proper solution but another hack until I can learn more.

Hi Pete,

Seems I'm a bit too late to avoid you suffering from a programming burn-out :wink:
But here is how I try to add new properties to my contributions. Don't know if it is a correct design, but it seemed to be working fine ...

  • A new input field is added to an existing node:

     <div class="form-row">
         <label for="node-input-newProperty"><i class="icon-tag"></i> newProperty</label>
         <input type="text" id="node-input-newProperty" placeholder="newProperty">
     </div>
    
  • To make sure it is stored (and communicated to the server-side), I add a newProperty with a default value 123 and a number validator:

    defaults: {
          newProperty: { value:123, validate:RED.validators.number() },
          ...
     }
    

    Then you will see that the validator has run, but the default value hasn't been applied (red triangle):
    image

  • To get rid of the red triangle, you can apply a custom number validator:

    defaults: {
          newProperty: { value:123, validate: function(v) { return !v || !isNaN(v) } },
          ...
     }
    

    This validator returns 'valid' if the newProperty doesn't exist ( see !v ). Indeed when I add a 'debugger' statement to the validator, you can see clearly that the newProperty doesn't exist:

    image

  • Another issue at this moment is that ( at the server-side ) the property also doesn't exist yet:

    image

    To solve that, I for a new property I always add the same default value here:

     function BlocklyNode(n) {
         RED.nodes.createNode(this,n);
         this.newProperty = n.newProperty || 123;
         ...
    

    Remark: this all happens when the user hasn't opened the config screen of the existing nodes in his flow.

  • As soon as the user opens the config screen of the node, you will see in the oneditprepare that the newProperty doesn't exist here yet (for existing nodes in your flow):

    image

    As a result the default value 123 will not be displayed on your screen:

    image

    I solve this by setting the default value again in the oneditprepare:

    oneditprepare: function() {
         $('#node-input-newProperty').val(this.newProperty || 123);
          ...
    

    Now the default value appears on the config screen:

    image

    Note that this problem only occurs for existing nodes in your flow. When you drag a new node to your flow, this default value 123 will already be available (so therefore I use || 123).

Hopefully this explains some things to you, and hopefully I didn't make things explode in your brain :wink:
Bart

5 Likes

In the html file I have values in the javascript area and 0 shows up in the input field but not defaulting to 0 if you already gave the node and get the update.

xw5: {value:0},

I was under the impression that those defaults are for the UI (property edit panel).
What happens if you also set a default inside the node's .js registration code? For example:

node.xw5 = n.xw5 || 0;
1 Like

the default only applies to new nodes when you drag them on. Existing nodes are already there and the new property is missing so you need to do as Bart suggests for the validator eg something like

validate:function(v) { return ((v === "") || (RED.validators.number(v)) }

and also as he suggests to add it to the oneditprepare to default it fully.

2 Likes

What’s a oneditprepare?

I’ll try that thanks…

I’m with you except for the oneeditprepare – no idea what that is…

Pete,
oneditprepare is a function that is being called as soon as you double click on your node (and your popup config screen dialog is being build). See documentation. In that function you can do all kind of initialization. E.g. make sure that defaults are loaded for existing nodes that don't have the new property yet ...

You can register oneditprepare when you register your node. Something like this:

    RED.nodes.registerType('Blockly',{
        category: 'function',
        color: '#FFAAAA',       
        defaults: {
            newProperty:  { value:123, validate: function(v) { debugger;
                                                               return !v || !isNaN(v); } },
            name: {value:""}
        },
        inputs:1,
        outputs:1,
        icon: "puzzle.png",
        label: function() {
            return this.name||"Blockly";
        },
        oneditprepare: function() {
            // Do some initialization stuff when the user double clicks on the node, just before the config screen is displayed
        },
        oneditsave: function() {
            // Do some stuff when the user presses the 'Done' button
        },
        oneditcancel: function() {
            // Do some stuff when the user presses the 'Cancel' button
        });
</script>

Ah, I do have one of those, I was looking in the wrong place, did that ages ago. Thanks for that.