I'm learning more and more as I go here. You guys probably already know this, but node.server.getCircles() (called from location.js via the $.getJSON in the oneditprepare section of location.html) is dealing with promises and as I understand it, the return I get back from circles = node.server.getCircles()
will never be the circle data because it executes asynchronously (like a system() call in perl (my native tongue)). So it's like forking a child process. And if I understand correctly, the only way to "get" the data from that call is to supply a callback method and that method is what needs to contain all the code of what I want to do with the retrieved data (e.g. make the select list items).
So my problem seems to be that I don't know how to supply a function to node.server.getCircles()
to create the select list so that it updates the "gui" (location.html). I have learned how to edit that function to accept a callback function and actually call it. I've successfully tested it to have it print the circles to the log.
I was looking at the method in oneditprepare in location.html:
oneditprepare: function() {
var node = this;
// Load the available categories from the server
$.getJSON('location/circles/' + node.id, function(data) {
// Show all available circles in the dropdown
let selectedCircle = "";
for (const [circleId, circleName] of Object.entries(data)) {
selectedCircle = circleId;
$("<option value='" + circleId + "'> " + circleName + "</option>").appendTo("#node-input-circle");
}
});
}
And I looked at what I understand is the method in location.js that receives that call. I tried to make it retrieve and process the data to set the data
parameter of the function passed in(?: function(data)
from the first snippet). It seems to set that parameter via res.json(...)
.
RED.httpAdmin.get('/location/:cmd/:id', RED.auth.needsPermission('location.read'), function(req, res){
var node = RED.nodes.getNode(req.params.id);
let circles = node.server.getCircles();
let circles_select = {};
for (var c = 0; c < circles.length; c++) {
let circle = circles[c];
let circleId = circle['id'];
let circleName = circle['name'];
circles_select[circleId] = circleName;
}
if (req.params.cmd === "circles") {
// Return a hash of all available circle IDs/names
res.json(circles_select);
}
}
The above doesn't work because circles
is a promise, not the hoped-for circles object. However, I can enter static values and it does update the select list, so it works in that sense. I just can't populate it from the circle data this way.
Given my current understanding, I need to supply a callback function to the call to getCircles that will do the setting of the select list options, i.e. it will make those .append() calls. I have a copy of the function that does accept a callback function. However, I don't know how to supply that function(data)
function from the $.getJSON call in the oneditprepare section of location.html as a callback function. I don't even fully understand the relationship between function(req,res)
and function(data)
. My naive interpretation is that res.json(whatever)
is a call to the function(data)
method. Is that close to correct? And if so, how do I pass that function "alias" (res.json()
) as a callback function to node.server.getCircles(callback)
?