Get ui-table data in JSON format

Hi nodered experts, I have ui Table where I can add/edit or delete any cells or rows.
Once the user is done adding/editing or deleting, I want to store the table data on a variable (might be global or flow) in JSON format.

I found this the same question here in forum:

However, this works only when you only want to edit data on your table.

What I want to achieve is, regardless of the user did to table (add/edit or delete row), after that, there is a button that when I pressed, it will save the table data on a variable.

Hoping for your guidance.

Tagging @Christian-Me , I hope you can help me here.

Merry Christmas!


Hi sorry to answer so late but I was busy with many other things

Are you already using the ui-table-handler? Then there is a documentation in the help panel.

You have access to the table data in two ways

A in the global or flow context as you configure it in the subflow config.

B by sending the getTable command to the subflow

I think I explained the process here

To get it formatted into JSON you only have to feed into a JSON node.

So I'm back at my computer, the last message I sent from my mobile phone... so I didn't get all the detail, including that you already found my old post

I' don't get the point here. Regardless if the user is editing the table the table (should) be present on server side and on client.

There are in general two ways work with ui-table data.
A) Fill it wit an array (complete table content)
B) and/or fill it by sending commands (You can first feed in an array and later modify or add data with commands. But an new array will always replace all data)

in B) you have to hold a copy of all table data on client side to replay the latest version of the table if a client connects. This is one of the main tasks of my ui-table-handler

Here is one example how I do it with my sprinkler system.

The Table holds the current program (the user can edit it but this is not relevant). If the user hit save (1) he will be prompted for a program name (2), the getTable command is triggered (3) the table handler merges the all data into one array (same format as the format as in option A) and stores it somewhere (and updates a dropdown to recall the saved tables

from the user perspective it looks like this

ui-table handler can also handle user sorted rows (and remember the sort order)

If this is something you like to achieve I'm happy to help. And if not I'm happy to help too :grinning:

Hi @Christian-Me ,

Apologies for the late reply, it's been holiday here in Philippines, super busy.
It's kinda confusing on my side. But I am still figuring it out how to fit the ui-handler subflow to get what I needed.

I believe this is easy for you to figure it out, and I really appreciate your help to me :slight_smile:
I will repeat my narrative of what I need.

Basically, what I want is to store the current data on my table to a specific variable (which is an array, so that I can use them to other function), in tabulator documentation, there is a command "getData" which returns the data in array, however this is not working on ui-table.

Other concern:
I actually didn't get this, there is a config on the ui-handler subflow "Tabulator"

On my ui-table I already defined this using msg.ui_control:

Now, I got confused whether the 2 should be identical.

But again, way back on what I needed, if this ui-handler can do this, I just need to know how can I use it properly, but if you know something that can do the job, then that is fine.

Again, thank you very much.


In Addition,

when I pressed the "save" button with msg.payload = {command: "getTable"}, this is what I get.

I get zero table array.

Hi @Henjoe, Merry Christmas, Happy Holidays!
Here is Berlin, Germany it is freezing cold (-10°C last night) and the first part of the end of year celebrations are done with a lot of cooking and time with the family

OK, let's do this :wink:

First you wire in the handler wrong. The ui-table-handler is wired into your data stream as a middleman. It first receives all your data (or parts of it) stores them and feeds in appropriate commands to ui-table. It receives data from the table to do it's thing:

You don't need to send commands by yourself as the handler does it for you.

it is important to identify the row either by msg.topic=(an index value); msg.payload=123 or in your msg.payload={$topic:1,aColumn=123}. you can define your Index in the config (here $indexbut you can choose what you want). Best to change your config rowPropety to 'payloadand choose a index property (by default it should be id` or any other column holding unique values to identify the row.

The tabulator holds the ui-table configuration object. So you don't need to inject it (but you still can). Or you can leave it empty and configure the table in the ui-tableconfig. or mix all methods. All config data (should) be merged together.

The other properties are described in the help panel. Don't forget to wire in a ui controlnode to trigger updates when tabs change

If everything goes as planned you should see three objects in your data panel (as configured in the context option)


TableConfig (data like visible columns or column width)
TableData (your data so far)
TableEdits (all data typed into cells. Separate from the data to avoid new data overwriting the edited cells)

and get your data as you already have done it

Hope this helps for the first step. Let's see how it works for you.


Hi @Christian-Me ,

Thanks for immediate response! Will try this :slight_smile:
Will get back once finished or I have questions.
Happy Holidays!


1 Like

Hi @Christian-Me ,

So far, this is what I got.

I got confused on your statement here that I need to identify msg.topic and payload:

As you can see on my screenshot above, my msg.payload is an array type feeding the ui-handler.
Do I need to recreate my msg.payload to be something like
msg.payload = {$topic:1, aColumn=123} ?

Thanks Christian!

For reference, this is my config on the ui-handler:


The help says (I added a little bit):

sending data to ui-tabel

  • sending an array as described in ui-table will replace the complete table and delete all table edits
    if msg.keepEdits=true is added the existing edits will be kept.

  • send an object containing the updated properties of a table row by sending msg._rowProperty_ where msg.topic should contian the index or the object contains the index property.

So if you send an array the table will be replaced. If you send objects cells of a specific row will be updated (without replacing the hole table).

Sending in an array on initialization is fine (but might be unnecessary if you configuretableDatato a file store). Then the handler do the work for you.


  • Wire back the callback outputs to the handler input
  • get rid of the $ chars for the row property and id (this is a homie convention specific thing)
  • switch your debug nodes to complete message (will make life easier)

Do you see your data in the data tab of the editor?

Hello Christian ! I am trying to follow the usage of the helper subflow as well as your examples in 'syslog' and 'remote devices'. i copied the .json files and imported them to a test nodered instance successfully, yet i still cannot figure out howto match the settings in the helper node with the demo/sample data and adopt the helper node with my columns / data.
i have a quite simple array of index, name and state (for power control) which i would like to display in a table, and also be able to change the state and (optionally) the name data fields, also triggering some action in the background. When using the ui-table node in the old fashioned way, the table gets reset and re-drawn each time i click on it, scrolling back up to the top - this is definitely not what i want. by searching for a solution which would allow the clicking of a table field, process the click (using the table output) and updating that one table field without altering the rest of table display and at the same time update just the currently visible portion of the table when other table data are changing.
when looking at your examples, i am simply overwhelmed by the various names , functions and designators in there and cannot figure out, which ones are mandatory like in your example and which ones i need to sync with my table data. may it be possible that the 'demo' data and the ui handler node in your remote device example do not match ? I am going to collapse the 'mess' i have created last couple of days into some essence and then attach to this post. anyway thanks a lot for your explanations and examples here - much appreciated and 'frohe Weihnachten' to Berlin !

Hi @ataelim, @Henjoe

I prepared a demo flow:

I recognized that the table handler not working well with the table data send as msg.payload so I did a few updates. That should work now. (OMG my own legacy code :rofl:). So please make sure that you get version 0.2.1

I recognized that sorting/moving columns is not working (as expected) any more. They either don't restore or are in a strange place. Have to go into the code of ui-table itself as the columns configs are merged there. But this has to wait unil next year :wink:

I added only basic functions (add rows, update rows, change row width, edit cells, hide and unhide columns) not to overwhelm everybody.

Let me know if how it works for you. Happy new year! :partying_face:

As the flow is to big to post it here please download it from here:

1 Like

Thanks for this @Christian-Me
Highly appreciated your hard work! :pray::pray: