Scenario:
NodeRED sits on a double network, can reach a backend and can be reached by the browser. The browser can't reach the backend directly.
A configuration node has two entries:
- baseURI (the URI the backend can be reached - not necessarily http(s)
- category: currently String
FIlling in the values and letting the node do its thing works like a charm. Now the challenge: each backend supports different categories and the "category" input should be replaced with a dropdown list showing the available categories. The backend has such a function.
The basic mechanic using a typeInput and reaching into the backend works:
// Edit snipped
oneditprepare: function () {
let apiList = getApiList(RED, $('#node-config-input-baseUrl').val());
$('#node-config-input-api').typedInput(apiList);
}
// calling backend
const getApiList = (RED, hostname) => {
console.log(`Retrieve API List for ${hostname}`);
let options = RED.settings.dominoConnectorApiList;
return {
types: [
{
value: 'apis',
options: options
}
]
};
};
On the NodeRED side:
const apiList = (baseURI) => {
// HOW can I run this at setup time with the baseURI
console.log('Running API List');
// Hardcoded for now
return [
{ value: 'basis', label: 'Basic CRUD' },
{ value: 'admin', label: 'Domino admin' },
{ value: 'pim', label: 'email, tasks, calendar (PIM)' },
{ value: 'poi', label: 'Office functions' },
{ value: 'setup', label: 'Setup REST' }
];
};
module.exports = function (RED) {
function DominoConnectorNode(config) {
RED.nodes.createNode(this, config);
const node = this;
node.baseUrl = config.baseUrl;
node.api = config.api;
}
RED.nodes.registerType('domino-connector', DominoConnectorNode, {
settings: {
dominoConnectorApiList: {
value: apiList(),
exportable: true
}
}
});
};
Or am I taking the wrong approach?
If you need the front end (i.e. the Nodes config HTML) to communicate with some backend.
then you need to register an HTTP Admin Endpoint.
Backend
RED.httpAdmin.get('/some-unique-URI-endpoint',RED.auth.needsPermission('flows.read'),
(request, response) => {
const myObject = [
{ value: 'basis', label: 'Basic CRUD' },
{ value: 'admin', label: 'Domino admin' },
{ value: 'pim', label: 'email, tasks, calendar (PIM)' },
{ value: 'poi', label: 'Office functions' },
{ value: 'setup', label: 'Setup REST' }
]
response.json(myObject)
}
);
Front-End
$.getJSON('some-unique-URI-endpoint', (data) => {
$('#node-config-input-api').typedInput(data);
})
Ensure you use a unique endpoint identifier (as it can clash with other nodes if to vague)
There is another option. But only for something that does not change until Node-RED (re)loads. The register function in the runtime allows passing of some data which can be read in the Editor.
As in this example:
/** 2) Register the node by name. This must be called before overriding any of the
* Node functions. */
RED.nodes.registerType(uib.moduleName, nodeInstance, {
credentials: {
jwtSecret: { type: 'password' },
},
// Makes these available to the editor as RED.settings.uibuilderxxxxxx
settings: {
// The server's NODE_ENV environment var (e.g. PRODUCTION or DEVELOPMENT)
uibuilderNodeEnv: { value: process.env.NODE_ENV, exportable: true },
// Available templates and details
uibuilderTemplates: { value: templateConf, exportable: true },
// Custom server details
uibuilderCustomServer: { value: (uib.customServer), exportable: true },
// Current version of uibuilder
uibuilderCurrentVersion: { value: (uib.version), exportable: true },
// Should the editor tell the user that a redeploy is needed (based on uib versions)
uibuilderRedeployNeeded: { value: uib.reDeployNeeded, exportable: true },
// List of the deployed uib instances [{node_id: url}]
uibuilderInstances: { value: uib.instances, exportable: true },
// uibRoot
uibuilderRootFolder: { value: uib.rootFolder, exportable: true },
},
})
The properties passed back have to start with the name of the node I believe.
In the example, the uibuilderInstances property is only correct at the time that Node-RED starts since it will change if someone, for example adds or removes a uibuilder node. So it is really a bit superfluous since I have to have an API anyway. I'll remove it one day. But the uibuilderCurrentVersion cannot change when node-red is running.
Good to know, I thought RED.settings are only for the runtime - every day is a school day
Haha, they are - except when they're not. 
How very true. And this has prompted me to improve some Editor related code where I turn on debug console output. Used to be if the node-red editor was accessed on localhost, it is now if the NODE_ENV variable on the server was set to "dev" or "development". 
A little off-topic, but I apply the same approach in .NET, but with clr "preprocessor directives".
One of my projects in github (.NET), used to try and connect to a server on the host, if a debugger was attached - but had reports that when they use the lib while developing their app - it would timeout.
So, I added a 3rd profile Debug - Local Server that adds preprocessor directives, that is checked before trying to connect to a local server.
#if DEBUG_LOCAL
// connect to local sever
#endif
meaning they can still debug without connecting to a local server, by using the default Debug profile