Using Node config in HTML file (access Node config from frontend)

Hello, I'm working on an OpenFaaS/NodeRED plugin.. I want for Node configuration in browser, to display list of possible functions in form of dropdown. I have started working on it, but I'm unable to access node configuration from HTML file.

On my node:

// openfaas-function/openfaas-function.js
 this.fetchFunctionList = async () => {
      const functionList = await this.agent.get("/system/functions");
      return functionList.map(func => func.name);
    };
// openfaas-function/openfaas-function.html
 oneditprepare: function() {
      const select = document.getElementById("node-input-name");
      // how to get node here for the line below?
      const functions = node.fetchFunctionList();
      select.options.length = 0;
      for (let i = 0; i < server.functions.length; i++) {
        select.options[select.options.length] = new Option(server.functions[i]);
      }

You can pass a nodes instance variables back to the editor using the 3rd parameter of the RED.nodes.registerType() function.

Alternatively, you can create a simple API. The serial node has a good example as does the v2 branch of uibuilder.

@TotallyInformation could you elaborate on the registerType option please?

I have performed a test passing {test:123} in the 3rd parameter of RED.nodes.registerType() in the .js file but cant see where I would pick this up in the .html.

Also, API documentation makes no reference to this 3rd parameter (unless I was looking at the wrong page?)

Cheers.

I'm almost certain he meant a third parameter in function in HTML file, after name of function and object with properties. So RED.registerType('node-name', { default: {} }, node) and node is the settings in here. But I need to check it out myself.

There is a lot of truth in your statement about documentation though, will try to document the stuff we will find out. :wink:

@kosciak the right way to do what you are asking is to create an HTTP Admin endpoint that your front-end code can call - as described here: https://stackoverflow.com/questions/41567175/send-data-on-configuration/41567832#41567832

The third argument to registerType has nothing to do with exposing individual node properties to the editor. It is used to declare any settings the node uses from the settings file that should be exposed to the editor. I thought it had already been added to the main creating-nodes docs, but I don't see it. The design note for it is here: https://github.com/node-red/node-red/wiki/Design%3A-Node-settings

But to reiterate - it is not what you need for your scenario.

1 Like

Thanks, this kind of pointer was exactly what I needed. Will look into it soon.

@knolleary thanks for the info.

Question...
For a static set of (config) data/options that is needed at both Client and Server side, is it valid to use RED.registerType or would you still recommend a HTTP Admin endpoint ?


++ Extra details to illustrate the above point (just in case)...

Lets say I had a fairly large (100 items) static set of (unchanging) options I needed available in both front end and back end.

  • At client I side will generate a dropdown in the node property editor.
  • At server side as object with values required for operations

e.g: Server side object...

var operations = {
  "Calculate TAN" : {"paramCount": 1, "fn", "tan"},
  "Calculate COS" : { "paramCount": 1, "fn", "cos"},
  "Add" : {"paramCount": 2, "fn", "add"},
  ...
  ...
  ...
}

In the editor (client side) I will generate an option list in oneditprepare and provide the users choice back to server side in one of the defaults : {} properties .

E.g. Client side code...

oneditprepare : {
  //make list of options for drop down
  let options = this.settings.operations.map(...)
  //populate dropdown
  ...
}

In the back-end, I will receive the users choice and use the properties e.g.

E.g. Server side code...

let op = operations[node.selectedOption];
let params = getParams(op.paramCount);
myFunctions[op.fn](...params); //call the function selected by user

If they are options hardcoded in your node, then the HTTP Admin endpoint.
If they are options you expect a user to provide via their settings file, you can use the node settings option of registerType.

2 Likes

@knolleary or @anyone_who_knows...
While we're on the topic of best practices for node creation I have another (related) question I hope you can help with.

Where would one store a 'common object' for re-use across all node instances?

e.g. Lets say I am developing a node called image and on my flow there are 10 instances. I would like each instance (server side) to be able to access some shared object {fonts:[...]} that are initialised only once.
PS. I don't mean a config node (this shared object has no parameters or user options and need only be created once & re-used by every node instance (server side only))

Hope that makes sense.

This topic isn't about best practices in general. Can you start a new topic rather than derail the original question. Thanks.

OK, done.

Hey @knolleary, I have followed the way you showed and was able to finish the functionality. I have a small question - is it possible to unit test this endpoint. Do you have ideas? I thought about it for a while but couldn't come to any sensible solution. I liked the 100% coverage I had before. :slight_smile: