How to use a core node inside of a custom node implementation

It's a JSON returned by the server. But unfortunately the list is not static as in the serial node implementation you linked to with the static list of baud rates. A user may have defined any number of pilight switches on his pilight server. So I don't know the size of the list beforehand.

But you can do a request to get the list right? Have a look at this https://github.com/johanneskropf/node-red-contrib-sox-utils/blob/2f37681ae6b5191a4c43d100794c6ee7b09027ca/sox_record.html#L67
and this
https://github.com/johanneskropf/node-red-contrib-sox-utils/blob/2f37681ae6b5191a4c43d100794c6ee7b09027ca/sox_record.html#L162
its a node im developing right now. Im new to the whole thing too. The first link is a jquery request that gets some information from somewhere, in your case it could be the pilight server or somewhere inside your js code and than automatically populates a dropdown which is at the second link above with the data from the requests response. In my case its not a pilight server i do the request too but an endpoint in the js you can see here:
https://github.com/johanneskropf/node-red-contrib-sox-utils/blob/2f37681ae6b5191a4c43d100794c6ee7b09027ca/sox_record.js#L299
where i do some stuff that i than send in the response which gets used.
I think what was hardest for me at the start was understanding that the serverside js code and the client side html don’t actually have a way to communicate from the get go except the one way road client to server with the values from the config you can access in the js/serverside part and that when you want to actually get data to the client side html dynamically you have to use http requests and or endpoints.
Once you wrap your head around it it fortunately is actually pretty straight forward :grinning:

Have you tried what I suggested? It will do exactly what you want, under the assumptions I stated

I'm still keen to get the drop down list in my custom node - given you still try to help me to get it impemented :slightly_smiling_face:. I will check the links the next couple of days in detail and hope I will grasp the JS coding idea.

From coding in go I'm used to create testcases - even the custom node is very simple I want to create them. Are there any rules/guidences how to create testcases for node-red custom nodes? Is there any test infrastructure available I can use?

Yes. But I found

var blist = [
                {value:"115200",label:"115200",hasValue:false},
                {value:"57600",label:"57600",hasValue:false},
                {value:"38400",label:"38400",hasValue:false},
                {value:"19200",label:"19200",hasValue:false},
                {value:"9600",label:"9600",hasValue:false},
                {value:"4800",label:"4800",hasValue:false},
                {value:"2400",label:"2400",hasValue:false},
                {value:"1200",label:"1200",hasValue:false},
                {value:"600",label:"600",hasValue:false},
                {value:"300",label:"300",hasValue:false},
                {label:"other",value:"other",icon:"red/images/typedInput/09.png",validate:/^[0-9]*$/}
            ];

which for me is a static list I don't have :frowning:

Have you tried this?

The link I posted should just tell you where you should put the $.getJSON, namely in the oneditprepare function.
Then you can have a dynamic list

To help you a little more, start with this

oneditprepare: function() {
    $.getJSON('http://YOURSERVER', function(data) {
        console.log(data);
    });
}

in your node html.
If you get the list of devices out of the console, then the next thing you need to do is to populate a dropdown menu with it. The serial node shows you how to do that

I see. Looks like I have a lot to read and understand the next couple of days. I will keep you posted :smiley:

no problem, we like to help, but posting complete finished solutions will not help you the next time. Therefore, it is always better to try and report on problems you encountered.

Edit: I looked into you code and it seems that you already retrieve the device list there. Therefore, the cleaner solution would be to create an http endpoint as JGKK suggests. But anyway, if you get it working without creating an endpoint, you can then change the code to the endpoint solution.

https://nodered.org/docs/creating-nodes/first-node#lower-casespecjs

Final reply for today: I just realized that doing the JSON call from the editor to your server is not a good idea for a variety of reasons (e.g. CORS), therefore, you need to do the endpoint solution directly.
Sorry for the confusion. I thought I make it easier for you.
In order to achieve that, look at the links JGKK has posted to his own nodes, they show it pretty clearly.

Something like this

RED.httpAdmin.get("/pilightswitch/devices", RED.auth.needsPermission('pilight-switch.read'), function(req, res) {
    res.json(glbl.devices);
});

combined with

oneditprepare: function() {
    $.getJSON('pilightswitch/devices', function(data) {
        console.log(data);
    });
}

for more details, look at JGKKs links

Not sure I get your point. I consider my code as not final given I'm new to JS - and thus I'm open for comments. But as long as I don't provide any code it's impossible to discuss the implementation.

Thx for the test code link.

I meant that it is not helpful if others give you the complete solution

Will do :slightly_smiling_face:

Hm ... there is some misunderstanding ... I don't want to get complete solutions. That way I don't learn any new stuff ... Why do you think I look for a complete solution? I just ask for some hints and links to start reading and coding.

Perfect, then we are totally aligned :slight_smile:

I am sorry if I said something that you misinterpreted, was not my intention.

You will see that populating such a dropdown list is indeed confusing first (was the same for me, and many others as well), but as soon as you have done it once, it is actually pretty clear.

2 Likes

I updated the html similar to @JGKK s code and now get a drop down list in the editor :slightly_smiling_face:

I also read this page about the events emitted by the editor just to understand what's going on there.

Then I tried to populate the list. When I hard code the items with

          $('#node-input-device').append(`<option value="SP1">SP1</option>`);`

I see it added in the list to the default entry. When I use $getJSON nothing happens. Looks like the request is not executed for some reasons. In addition I noticed console.log does not log anything :frowning_face:

The loop I use to retrieve the device names works fine in the js file (It's not an array as in @JGKK s code but a simple key value list and the key is the item I want to add in the dropdown list).

oneditprepare: function() {
          var node = this;
          console.log("ONEDITPREPARE");
          $.getJSON('http://192.168.0.12:5001/config?media=all', function(data) {
            console.log(data);
            Object.keys(data.devices).forEach(function(key){
              $('#node-input-device').append(`<option value="${key}">${key}</option>`);
            });
            $('#node-input-device').val(node.device);
          });
        }

Any hint what's missing or wrong in the code? I see some light at the end of the tunnel ... but there are still some steps I have to take.

Actually I also just use a hard coded URL which has to be changed later on to use the host and port from the config node. But first of all I have to get the list populated with the JSON response of the pilight server.

do you get any error in the browser console?

Since the editor is not the same origin as the pilight server, you might run into CORS problems with the JSON request. Therefore, the way of exposing the endpoint from the Node-RED runtime is the better solution (again sorry for the confusion).
Maybe directly try the endpoint solution?

Just to make sure. You have to look in the browser console to see the console logs made from the html part of your node as this code gets executed client side in the browser.

I'm sorry I didn't notice I have to check the client side console :blush:. And yes: Its a CORS issue

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://192.168.0.12:5001/config?media=all. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

As far as I understand I just have to set the request header to

Access-Control-Allow-Origin: *

which I can do with ajax (Found this page which shows hot to set the header)

Sorry but I'm lost now. Doesn't it make sense to get rid of the CORS issue? Should I go the endpoint solution way? Do you mean this when you talk about the endpoint solution? But why should I go the endpoint solution? I think it's easier to stay in the node code instead of redesigning the whole custom node to use an endpoint.