Use of configuration node - needs deploy first?

So i read a lot in the documentation, but several things appear not to be quiet obvious.

I want to create several custom nodes which should have access to a configuration node providing broader common information like:
Baseurl, Email,Password, Port and other stuff that might be relevant to share.

One of the scenarios i was thinking of how to use it, was by doing a automatic signup with the provided credentials for example to retrieve a JWT, so all my subsequent API calls regardless where can use the token.

The problems here i'm facing:
Drop my first custom node on the flow to generate the config via add dropdown,
listen to config change will result in the id being show, but when trying to call a special endpoint in the config node node.js code the endpoint isn't available until i deploy the flow.

Is it somehow possible to force a deployment once a node has a configuration assigned
to make it work?

Or will i have to re-think of how i build up my custom node(s) that way?

So you've hit a slight oddity of the way that Node-RED works in that you can have nodes in the flow that have not yet been deployed but still may have important info.

Thankfully, there is a way around this. Node-RED has some events that are triggered in the Editor when nodes are added/modified/removed and before changes are deployed. From those, you can watch for changes happening to the specific nodes you are interested in.

RED.events.on is the handler. nodes:add, nodes:change and nodes:remove are the events. Each handler has a callback function that is passed the node object.

There is an example here:

1 Like

Sounds like something i can try atleast, out of curiosity (because like i said some things like this aren't well documented) what kind of node do i get passed here. will it be the node instance of the html or the node.js part?

Also a shot in the blue, are there any other references despite the one you shared already?

And i also recently found some package where RED.publish/subscribe was used (i think that's yet an other mechanism which lacks documentation, or i'm completly mistaken on this and it doesn't exist) but could be of interest.

Just if you may know any sources for that, or how i could utilize this mechanism as well?
I would kindly apreciate it :slight_smile:

Looks like there's no trace of such a mechanism in the NR source. If used, it could be a custom pattern patched into the RED namespace. Node (and even more plugin) developers tend to be quite ingenious to achieve their objectives. :wink:

The best thing to do is what I do, stick a console.log in the code and see what you get. I can never remember the details because it isn't often you need to dig into it. I would expect it to be the HTML version since you are getting it from the Editor and not the runtime.

There is a RED.comms.publish "Websocket comms between the runtime and the editor." That is a runtime API.

https://nodered.org/docs/api/modules/v/1.3/@node-red_runtime_comms.html

Use RED.comms.publish in the runtime and RED.comms.subscribe in the editor

const msg2 = mod.RED.util.encodeObject(
    { id: this.id, z: this.z, _alias: this._alias,  
      path: this._flow.path, name: this.name, 
      topic: msg.topic, 
      msg: { payload: 'hello' } 
    },
    { maxLength: 1000 }
  )

mod.RED.comms.publish('debug', msg2)

In the editor:
Send msg to debug panel - RED._debug

Thanks a lot for some guidance here.

My final approach of handling the issue regarding "needs deploy first" (also covering the case of "config not yet selected") is like so (omitting the HTML part):

function fetchData(configid) {
            $.getJSON("endpoint-for-data-fetch" + configid)
                .done(function (data) {
                    var ddData = [];
                    for (let index = 0; index < data.length; index++) {
                        const element = data[index];
                        var ddEntry = {
                            value: element.someValue,
                            label: element.someLabel,
                            hasValue: false
                        };
                        ddData.push(ddEntry);
                    }
                    patchUserSelectionTypes(ddData);
                })
                .fail(function (error) {
                    if (error.status === 404) {
                        patchUserSelectionTypes(errorTypes);
                    }
                });
        };

        var isInit;
        const defaultConfigValue = '_ADD_';
        const defaultTypes = [
            {
                value: -1,
                label: 'Please select a config first',
                hasValue: false
            }
        ];
        const errorTypes = [
            {
                value: -2,
                label: 'Please deploy this config first',
                hasValue: false
            }
        ];

        function initializeUserSelection() {
            isInit = false;
            $("#node-config-input-userSelection").typedInput({ default: -1, types: defaultTypes });
        }

        function patchUserSelectionTypes(types) {
            $("#node-config-input-userSelection").typedInput("types", types);
        }

        function onPrepare() {
            var node = this;
            isInit = true;

            $('#node-input-config').change(function () {
                var configId = $('#node-input-config').val();
                if (configId && configId === defaultConfigValue) {
                    if (!isInit) {
                        patchUserSelectionTypes(defaultTypes);
                        return;
                    }
                    initializeUserSelection();
                    return;
                }

                if (isInit)
                    initializeUserSelection();

                fetchData(configId);
            });
        };

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.