Can a node property be an object?

I am trying to create a generic node for uibuilder that is capable of creating many different HTML elements, some of which may be compound (e.g. multiple HTML elements).

For this I need to be able to have a variable set of node properties. These will be different depending on which type of element you choose. So I cannot predict in advance which properties will be needed.

I would, therefore, like to dynamically create a set of HTML inputs (not a problem, got that covered) that output to a single node property. My thinking was that the property would be an object with properties related to the inputs.

I can easily do the dynamic bits using jQuery. But when I manually update the node's property, it doesn't seem to tell node-red that the node instance is dirty and a re-deploy is needed.

What I don't know is whether a node property can be an object?

And if so, how do I tell node-red that a re-deploy is needed? (I know I should know this part but it always seems to escape me). If I set the node's changed property to true, the Editor shows a blue dot but the deploy button is not activated.

Just issue (on the client side)

RED.nodes.dirty(true);

I personally amend this by

RED.view.updateActive();
RED.view.redraw(true);

Job done!

Doh! Well, that is going into my new Obsidian "knowledge garden". :slight_smile:

I'm not sure, an object is supported. Yet you (usually) can easily jsonize the object & store it as a <string>.

Now that I can tell node-red to deploy, I can test whether an object is supported. If not, as you say, I can stringify it.

BTW, you need two things if you are manually changing a node property:

this.changed = true     // gives you the blue dot
RED.nodes.dirty(true)   // activates the deploy button

:sigh: doesn't look like passing an object works - oh well. Nice thought.

Thanks for your help Ralph.

Passing an object from where to where? Sorry, you got me curious about what new tricks you are working on. You are not referring to saving an object in the editor for your node's configuration and having that passed to the backend?

Yes, from the Editor to the runtime. Because I don't know what configuration properties the node instance will have since they will change depending on what option is chosen.

Think about the number of nodes that Dashboard has in the palette. I don't like that and I want to just have 1 node in the palette - uib-element. That node will let you chose what type of thing you want to add to your front-end UI. A list perhaps or a table or just a table row. A "card" maybe. All of these should be choosable from a single node.

The element config tab is created dynamically from <template> tags in the html file when you click on the tab. The template is dynamically added to the Editor panel based on the Type. A jQuery deferred event handler deals with changes to the dynamic data, captures it and squeezes it into the singular node property for deploying.

Well, that's the theory - if I can get it working!

Woo-hoo! Looks like I was wrong. Another error was hiding the correct result and it seems that you CAN pass an object. That will save some processing.

1 Like

Thats good news. Well, I grab some data and convert it to an array before sending it to the backend in oneditsave and it arrives as a regular array, nothing stringified.

oneditsave: function () {
      this.players = [];

      $('#node-input-players-container')
        .editableList('items')
        .each((index, row) => {
          this.players.push(row.data('data'));
        });
    },

scratch that thought, maybe it is stringified. either way, it works

1 Like

Just to confirm, node properties can be any json type. The change node has a property that is an array of the rules to apply.

1 Like

It all works! :mechanic:

Loving the use of <template> tags to keep things tidy. Eventually, I'll probably move the templates to API served files for proper lazy loading. Gotta love how easy jQuery makes stuff like this. Might be ancient but it still kicks a$$.

Had to mess around a bit to get the deferred event handler to just mark individual input's as changed (by setting a data-changed="true" attribute. Then in the oneditsave function, I select everything that has changed and apply to the node property then mark things as changed and dirty. That way pressing cancel doesn't mark the flow for deploy.

Not sure I've got the undo processing correct but enough for one night.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.