Dumb question about editing a node

Yes this code is now on the server/backend side. So “all” it now needs to do is whatever you need to do to get your list of circles and then set that json object into res.json() to return it. (And handle any errors that may occur if you fail to get anything.

Ah! I figured out how to access the server node from an undeployed node's edit interface. I had to look at Bart's repo for the thing I was missing:

I just had to access the value from the form.

Still making progress. Slowly, but surely.

It's a brave new world. Lot to learn but rewarding when the light bulb lights up!

1 Like

It took me awhile to get the next select list to autopopulate (people), but I just finished that and it's updating whenever the circle selection changes now. Next is places. Then I'll need to figure out how to save the selections. Places should go rather quickly because it's the same basic process as people was.

Yep. Just finished places. So now there's:

  1. Save edit selections
  2. Implement logic to trigger node output when person, place, and event type all match the detected event

I will likely squash the current message type or maybe make a different node.

I'm also a bit wary of the possibility that multiple copies of the same node with different settings may cause problems. I've had issues with copies of other node types.

Another dumb question. I've been editing code inside ~/.node-red/node_modules/node-red-contrib-life/nodes and restarting node red to see the effects. It seems this is insufficient for saving the new inputs I've been adding.

At first I thought I needed to do something explicit to save selections from the edit dialog, but I looked at the pre-existing inputs before I started changing things and there appears to not be anything that saves those inputs, yet changes are saved.

What do I need to do to save selections from the edit dialog?

The doc I've read talks about installing a node, but I've been tweaking an already installed node. I know I've jumped right in the middle. How is development normally done?

Hmmm, grepping files, it looks like the settings are saved in flows_raspberrypi.json. I guess I need to explicitly set the select lists based on the values.

OK. I figured out that my confusion before was due to change event handlers were being triggered when I didn't expect them to and the fact that (and correct me if I'm wrong):

New selections (if they exist) are in: $("#node-input-whatever").val();
Previous selections (if they exist) are in: node.whatever

And I was also seeing some asynchronous settings of the selected items because I was populating the select list and setting the selected item in different threads.

I thought I had worked that all out and moved all manipulations (clearing, populating, setting, and triggering) into the callback function, however now the select list selections I'm setting are not getting set and the select lists always present with no selected item (no default and no previously selected item and I can't seem to figure out why.

Of the 3 lists I'm working on currently (circles, places, and people), the one that does have a selected item is the circles select list. The other 2 are populated but don't show their previously set values. And another thing that confuses me is that making selections doesn't usually cause the deploy button to activate.

So let me ask a few questions:

  1. When the edit dialog comes up, the only things that should be saved WRT select lists is the value of the previously saved selection. The other items in the list need to be re-populated and the previously selected one has to be explicitly selected. Is that all correct?
  2. What has to happen in order for the deploy button to activate? Why can I make select list selections and click done and the deploy button is still grayed out?
  3. When is a call to an input's change function triggered other than calling ...trigger('change')? And why would it be called before the running of the top level code in oneditprepare?
  4. Does ...trigger('change') need to be called to show the previously selected select list item?

According to my console prints in the browser's web inspector, I'm setting values in $("#node-input-whatever").val('value here') and those values are in the list I populated before setting the selection, so I don't understand why the lists initially show no selection. Do I need to change like, the default or something? I wouldn't think I do because my simpler node-input-event select list and my node-input-circle select lists show the correct selections based on my calls to .val(...).

One thing I suspect may be a source of one problem is that in oneditprepare and in the change function for circles, I'm not only making the server call to get the values to populate the circles select list and set its selection, but I'm also making 2 other server calls to populate the people and places given the selected circle. I.e...

        oneditprepare: function() {
            var node = this;
            var configNodeId = $("#node-input-server").val();
            $.getJSON('location/circles/' + node.id + '/' + configNodeId + '/none/none', function(data) {

                ...

                $.getJSON('location/places/' + node.id + '/' + configNodeId + '/' + circleId + '/' + placeId, function(data) {

This does populate everything correctly. It's just the selections and the deploy button activation that doesn't seem to work...

OK. I've gotten places and circles to fully work, but it seems overly complex. I'll post what I've got once I'm done to see if you guys have any tips for simplification.

Congrats! I'm guessing the reason you haven't been receiving as much help as you could is the fact you seem to be just hacking away some existing node code for your own purposes.

Two questions to clarify the above:

  1. Are you working on a general purpose improvement to an existing contrib node that others could also benefit from?
  2. If so, are you planning on contributing the improvements to the repository of said node or perhaps thinking of forking it to another name?

If planning on contributing back to the existing code, I would hope you'd get better assistance by creating a feature request issue on its repository and letting the developer know what you've already accomplished.

Edit: Is this https://flows.nodered.org/node/node-red-contrib-life the node you're working with? If it is, then what I said doesn't apply as it doesn't seem to have published its repository URL.

What I see is that it's source code is GPL-3.0 licensed, so if creating a public fork, you'd need to be careful to include the licence, copyright etc. information required a GPL-3.0.

Yeah. I'm sure that's not the only reason. My questions haven't been very well constructed.

  1. Yes.
  2. Yes. I have a fork. I branched and created a PR from that branch into my own master and tagged the original author for review. The branch currently only has the bug fixes. Basically, I was testing the waters to see if he'd like a PR to his repo. I'd created a couple issues on his repo, but he responded that he didn't have time to work on it, which is why I decided to take a stab at it.

And yes, that is the node. It does exist on github. I thought I'd posted the link, but maybe I haven't:

Rob

1 Like

Is there a way to distinguish whether a change has been triggered by explicit user selection versus trigger from a call to $("#node-input-place").trigger('change') (from node-input-circle's change code) or do you have to make the change to node-input-place inside the circle change code and only trigger place (so it can trigger subsequent changes) when you actually change its selected value? Or should I change the children and grandchildren in the change code of the parent?

Because I'm currently triggering in every case and determining what to do to each select list based on what is different when looking at the undeployed value and the selected value of "myself" and my "parent", and when neither are different or both are different, the only way I can know what to do is to know how the change was triggered. E.g.: the user changes the circle from 'any' to a specific circle, which triggers place to repopulate its select list (adds places based on the circle), then they change the circle back to 'any'. The place change code could base what it does differently based on whether it was a place selection change or a circle selection change, but since both match the original pre-deployed values, it doesn't have enough information to know that it needs to clear out its list of places.

I suppose I could additionally check the length of the select list options, but I thought I'd ask if there's a way to know how the change was triggered... What's the conventional way of dealing with this? How should I be doing it? I suspect this is one reason why my code seems too complex.

Does this might help you?

That's exactly what I was looking for! Thanks!

1 Like

Ok. This is exciting. I have a working node. I've only tested the simplest case, so I have more testing to do, but I noticed one issue:

I was testing with 2 copies of the location node and only one was getting a status update. I noticed that there is a thing in the "server" to set a callback method when there's a change. I assume I need to make that a callback array and loop on it whenever I send events to location nodes? Is it that simple or do I need to do other things?

OK. I think I did it. I still have some more testing to do and some clean-up, but this seems to work in the simplest case and in the case of setting "first to arrive at a place". Here's my latest branch:

I created a PR from my latest branch to my master, if anyone feels inclined to review my efforts and find any issues (though I wouldn't expect anyone to). I really appreciate all the help you guys provided. Aside from some debug print and other general code cleanup (and barring any bugs that pop up), I think I'm just about done.

I didn't end up using the change event source, which I suspect could solve some edge cases I have yet to encounter, but I haven't been able to intentionally make them happen, so I might be good.

Of course, as soon as I post that, my parents arrive at their house and the tests I set up reveal a bug. The location nodes I had deleted from my flow appear to be generating output. I guess there's something I need to do to remove callback functions from deleted nodes...

OK. It looks like I need to add code like this to the location node:

this.on('close', function(removed, done) {
    if (removed) {
        // This node has been disabled/deleted
    } else {
        // This node is being restarted
    }
    done();
});

However, I'm not sure how to identify the correct callback function to remove from the array in the server node... I suppose instead of an array of functions, I would create a hash, but what identifier for a location node can I send when adding the callback function? Is node.id a thing?

What's the difference between this.on('close'... and oneditdelete?