This is my first post here and I'm new to NodeRED and to js/HTML in general - I'm usually a backend guy -. I therefore have zero experience so please, forgive me .
I followed the tutorial on how to create a new node, and I have created several slightly more complicated based on that. Now I'd like to do something more useful even though I realize that matters get a lot more difficult.
What I'd like to do is:
Call an HTTP API - remote server - that returns a JSON.
Return the list of selected options when the user pushes the "Done" button.
So regarding point 1, I have implemented the HTTP call in the .js file:
module.exports = function(RED) {
function JsonNode(config) {
RED.nodes.createNode(this,config);
const https = require('https')
const url = "https://test345.free.beeceptor.com/test";
https.get(url, res => {
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
data = JSON.parse(data)
console.log(data)
})
}).on('error', err => {
console.log(err.message)
})
}
RED.nodes.registerType("json-ex1",JsonNode);
}
Again, because based on what I found, I think I understood that's the best way to call a remote endpoint.
Then, for point 2, based on what I have seen, I should loop into the result and build the multiselect using the oneditprepare method. So I realize this is a newbie question, but how would I access data retrieved from the previous HTTP call here?
Regarding point 3 instead, I do realize that the function corresponding to the action I mentioned earlier is the oneditsave but again, I could not find an explanation of how to access the multiselect output.
I hope my explanation was clear,
Thank you in advance!
Urm, you are rather jumping straight into a very deep rabbit hole here I think
The first question I have to ask is: why? On the face of it, Node-RED already has core nodes that will do what you want.
I can understand though if you are doing this just as a learning exercise. But you chosen something fairly complex to jump into as a starter project.
Without looking in detail at your code, I'd guess that you are falling foul of JavaScript's async complexities. With things not happening in the order you expect them to. Because you are going into an async function.
Yes I do recognize that. The point is that I'd need this custom node to fit into something else which uses the output of the selection, and I'm sure this can be achieved with core nodes - done that using an injected sample -.
But since you say that this one could be achieved with core nodes, how could I? I mean, I could do the call with an HTTP request node, but then I'd go back to the original problem (i.e., having such payload available in the HTML file of the custom node) .
Is there a resource you recommend where I can fill my js/HTML gaps?
Thanks for your answer. I read somewhere - might be horribly wrong - that ajax calls on the HTML file are done to local resources. In my case, the endpoint would be remote, and I'm using a mock server atm to simulate it.
the html file ajax calls are typically to the node-red server - so that is often local but may be a different box to where the browser/editor is being viewed. there i s nothing to stop you pointing it somewhere else - but it would be a brave node that pointed to an external 3rd party server and expect it to be there all the time. May be ok for a private node where for example you are pointing to some company resource - but probably not a good idea for a node you intend to be public.
Based on what you say I believe it would be better if I did the request using the core HTTP request node, and pass the response to my custom. But in this case, should I access the response payload again using ajax in the HTML file? If so, is there a resource that indicates how to access node-scoped variables?
Where you put the HTTP Request is depending on what you are doing.
for example, if you hard code an internet address in the server-side code - then the node-red server MUST have internet access - something many node-red installations do not have (for security reasons).
Conversely, if the endpoint is called from client-side, more often than not, the user and his browser does have internet access.
Like i said, it depends on what you are attempting to achieve.
Where is this other resource? Is the URL settable by the user on the client side?
In the real use case that would derive from this, I'd expect the call to be localhost/something. But for the sake of testing and understanding, I was using a remote HTTP mock server right now.
Based on what you say though, I'd prefer the call to be on the client side. Again, both is this use case and in the real one I'm thinking of, I'd expect the URL to be fixed.
well localhost will be local to the browser - so you may not actually want that in the general case... - or you may... - but yes nothing to stop you experimenting. It should work either way - but make sure you test the different configuration scenarios before you ship it
Haha I'm not really gonna ship it, it's a kind of "useless" project even though the use case is real.
So, in this scenario -i.e., keeping the call remote- I believe that having it in the oneditprepare would make sense. The thing here is that when I move the same call that I have done previously in the js file:
oneditprepare: function() {
const https = require('https')
const url = "https://test.free.beeceptor.com/tags";
https.get(url, res => {
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
data = JSON.parse(data)
console.log(data)
})
}).on('error', err => {
console.log(err.message)
})
}
I get this error when clicking on the Node:
ReferenceError: require is not defined
at Object.oneditprepare (:13:27)
at t (red.min.js?v=2.2.0:18:378152)
at E (red.min.js?v=2.2.0:18:379525)
at Object.open (red.min.js?v=2.2.0:18:391820)
at i (red.min.js?v=2.2.0:18:503894)
at Object.show (red.min.js?v=2.2.0:18:505105)
at Object.edit (red.min.js?v=2.2.0:18:392449)
at SVGRectElement.at (red.min.js?v=2.2.0:18:209002)
at SVGRectElement.i [as __onmouseup] (vendor.js?v=2.2.0:35:7943)
Does it have to do with the fact that I'm on client side now?
Thanks for the support. I managed to do this part (i.e., call to the HTTP endpoint, and building the multiple selection accordingly). Here is the code, as you might have understood I never used HTML and js so