How can I avoid this? The server retrieves all device data which then later on will be used in the nodes. For me the only way to get this done is to use a flow context. Is there any other way to share data between the server and the nodes?
Thats what configuration nodes are for:
https://nodered.org/docs/creating-nodes/config-nodes
They can provide data shared by several node
You don't need to use a flow or global context variable to do that, only the node's own context. Indeed, you don't even need to do that unless you want flow editors to be able to see the content using the context sidebar.
That is because, when it starts up, Node-RED does a require
on your node (which is written as a node.js module for that very reason). That creates a master instance of the node. Any variable you put inside your node's .js file that is outside the part that actually handles each individual instance will be "global" to all deployed instances of your node.
Have a look at the uibuilder code as an example. I create some variables outside of the exports
part and these are then common to all deployed instances of uibuilder. Using that, I can keep track of how many instances are deployed and what their URL's are (to ensure uniqueness). Similarly, you will see that I only add other front-end libraries (folders) into the static server list once no matter how many instances you have deployed.
Indeed they are. But again, they are not always needed as I explain above. In uibuilder, I could have used a configuration node. I don't use one because I don't need to allow an editor to be able to choose settings that have to be shared. Instead, I make use of the way that node.js handles modules.
Sounds that's what I'm looking for and don't have to use any flow config I had a look into your ui code and then added following code in my node implementation - similar to you in your code - but when I install my custom node it's failing. Both ways to require xmlhttprequest fail
// const xmlhttprequest = require('xmlhttprequest')
// var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequestconst glbl = {
devices: null
}
and later on use
var XMLHttpRequest = xmlhttprequest.XMLHttpRequest; xhttp=new XMLHttpRequest(); url="http://"+target+"/config?media=all";
node --check pilight-switches.js
gives no error. So I'm lost now. Any hint what's wrong here?
You have to do the context.get(ārequireā)
This should be the first statement before const xmlhttprequest? Why don't you have this in your code in https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/master/nodes/uibuilder.js ?
what exactly is failing?
I have some test flow which just triggers my custom-code-node which should query the defined devices on pilight and then sends a REST request to turn a (as of now) hard coded switch on or off. When I import my custom code into node-red I get an error message in the ui my custom node is not available when I add the require statements. When I comment them out the custom node is available but fails when a xmlhttprequest object is instantiated because of the missing require. So it looks like the required statement causes an error. Frankly I don't know how to get more details about the import error
do you have installed the xmlhttprequest package?
Please show more code and the exact error message, otherwise it is just guesswork on our side
I agree. I just pushed my current code here https://github.com/framps/node-red-contrib-pilight_switches/tree/master/nodes
During import I get an error message waiting for pilight_switches be defined when I uncomment the first line in pilight_switches.js. If I comment it out I get an error in https://github.com/framps/node-red-contrib-pilight_switches/blob/f060295ae879804a124d694f60a24438a033d7a0/nodes/pilight-switches.js#L44
xmlhttprequest not defined.
in your package.json I do not see the xmlhttprequest as a dependency.
Therefore, I ask again, have you installed the xmlhttprequest package?
Sorry, answered that on my phone - you are doing a custom node of course not a function, my bad.
@cinhcet You made my day
I had xmlhtpprequest in my node-red package.json but I didn't know I have to add this to the package.json of my custom node
I just added
"dependencies": {
"xmlhttprequest": "^1.8.0"
}
in my custom node package.json and now I can use xmlhttprequest
With your help I managed to create a custom node for pilight switches. It works fine as far as I can see. There is one piece missing: I would like to open a dropdown list when a node is created and the user can select the pilight device name the node should represent. The devices are retrieved from the pilight server and thus it's possible to pupulate a dropdown list. Is there any sample code available or any link which explains how to use a dropdown list ?
This is my first javascript code I write. If somebody has some spare time I appreciate to have some code review and comments. The code is not very complicated and it will not take much time for an experienced JS/node/node-red folk
You can for example look at the code of the serial node:
Thats how i learned. You pretty much have to do a jquery or ajax request from the html part of your node (https://github.com/node-red/node-red-nodes/blob/41d9f18608559cae8e27d22f9acf9e6216ef0ef9/io/serialport/25-serial.html#L395) in the on edit prepare section and than create an endpoint where that request goes and gets answered right at the bottom ov the js part of your node (https://github.com/node-red/node-red-nodes/blob/41d9f18608559cae8e27d22f9acf9e6216ef0ef9/io/serialport/25-serial.js#L461).
Thank you very much for the links. I didn't expect a drop down list to be that complex to implement. As you can see in my code I'm familiar with coding but not with JS coding. If I have to do it this way it's too time consuming for me
Frankly my local implementation works fine but I thought it's worth to create a custom-node for the node-red community because I have some insights in pilight REST API and programming ( ... not JS ... ) .
From a convenience perspective a drop down list would be great but I now will stick with the current implementation and a user has to lookup the pilight device name when he creates a node-red pilight switch node. I have to add some additional error checking and reporting code to catch typos but at the end there exists a custom node for pilight for the community
Do I understand you correctly that you only need that list in the editor and not the runtime?
Then you can also retrieve the list in the editor code, e.g. using jquery, to populate the list.
Yes, I only want a user of the pilight switch to present a drop down list when he creates the node. The list contents is available at this point in time. I just have to know how to present the list and how to retrieve the selection
Is it a fixed list or do you have to work out at editor run time what to put in there? A fixed dropdown list is very easy, it is making it dynamic that makes it more complex.
you said you get this list from some server, right? I guess as a json file? Then find out how to use jquery to get a json file into the editor of your node, something like $.getJSON('http://YOURSERVER', function(data) { blablabla })
You do that in an oneditprepare function, like here https://github.com/node-red/node-red-nodes/blob/41d9f18608559cae8e27d22f9acf9e6216ef0ef9/io/serialport/25-serial.html#L311