Join specific array field in a string separated by blank space

Good afternoon everyone,

In the data structure that I have in the image below, I need to join the string that is in the field "filename" of all the positions of the array ("rowSelection") in a single string separated by blank space.
I've tried with the join node and with a function node that joins the payload but I don't get results :frowning:
The data structure is as follows:
image

If anyone has any idea how I can achieve this, all help is welcome.

Thanks all for your contribution

in a change node using JSONata expression :j

$join($$.ui_control.rowSelection.filename, " ")

should work un tested as you supplied no data to test with.

Thanks @E1cid,
I didn't add the rest of the flow because I thought I would add more stuff.
However I let you down my flow.
I've already put the change node that you referred to (I named the node "join_file_names"), I've put a debug node in front of it but the result hasn't changed.
I'm probably not doing everything as you suggested.

I can't leave the flow code here because of the character limit in the post but I'll leave the flow file if you can help.

Thank you very much for your attention

flows (3).json (52.0 KB)

I need a copyable version of this so I can paste it in to test. If you go to debug panel use the copy value button to copy the data and paste here between backticks, use the </> button

ui_control.rowSelection (path copied for the line "rowSelection: array[4]"
Value copied for the same line:

[{"id":1,"filesize":"82K","filename":"datalog--2021-6-1--13-27--0.csv"},{"id":2,"filesize":"142K","filename":"datalog--2021-6-1--13-33--0.csv"}]

ui_control.rowSelection[0].filename (path copied for the line "filename: ..."
Value copied for the line "filename: ...":

datalog--2021-6-1--13-27--0.csv

Do you need more data or was it enough?

Thanks again

You have not supplied the data requested , as said i need the info in the image in a copyable format. Please goto the debug pane and use the copy value button on the ui_control object.
the button will appear when you hover the mouse where my cursor is in image below

{"callback":"rowSelectionChanged","rowSelection":[{"id":1,"filesize":"82K","filename":"datalog--2021-6-1--13-27--0.csv"},{"id":2,"filesize":"142K","filename":"datalog--2021-6-1--13-33--0.csv"}]}

I'm sorry but as I'm not very experienced I didn't understand.
I think I'm giving you the value of the ui_control object now

Ok tested now and the expression worked
here is a example

[{"id":"496ff00c.abfe5","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"ui_control","v":"{\"rowSelection\":[{\"id\":1,\"filesize\":\"82K\",\"filename\":\"datalog--2021-6-1--13-27--0.csv\"},{\"id\":2,\"filesize\":\"142K\",\"filename\":\"datalog--2021-6-1--13-33--0.csv\"}]}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":4920,"wires":[["14a0bae3.68179d"]]},{"id":"14a0bae3.68179d","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$join(ui_control.rowSelection.filename,\" \")","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":4940,"wires":[["131564fb.f801db"]]},{"id":"131564fb.f801db","type":"debug","z":"b779de97.b1b46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":4940,"wires":[]}]

I think you where setting msg.ui_control.rowSelected.filename, this would not work as rowSelected is an array so you could not set a property called filename.
In my example i have set it to msg.payload, but you could set it to any msg property you wish

Are you sure you really need to do that? What are you going to do with it?

Hi @Colin
The idea is to have the name of all selected files from a table, separated by blank space and in a single string to feed a command to eliminate files from an rpi.

I think I would probably use a node red fs node to do that, deleting them one at a time. But if you want to do them all at once then that is fair enough.

Thank you very much @E1cid

I made the necessary changes for the case of my flow and it is working properly.

Hello again @Colin,

After some tests and based on the behaviors I got, I read your suggestion again and I think you are correct.
In the idea that I explained to you, it is not possible to build the command to delete with the string that contains the names of the files to be removed, as it will only delete the first file until it finds the blank space and then the command is incorrect and does not delete the following ones.

Do you know how I can run a for loop or forEach and run the remove command for each name contained in the filename field of the array?

Thanks again

What command are you running?

To do it one at a time feed it through a Change node to Move the array object into msg.payload, then through a Split node which will give you one message per element in the array, then another change node Move the filename into msg.payload, then you can feed that into the delete node in node-red-contrib-fs-ops

I will use the command "rm -rf" because I need to eliminate 3 types of files, 2 are normal files and the other is to eliminate 1 or more directories. As I need the "-rf" for the directories, I tried it on normal files, it works too.
The problem that I will also have is that for each of these 3 types of files I have, the command will be the same as the exception for the folder in the directory, which is different. I have to find a way to change the last folder in the path depending on which file is selected to delete.

I will try these changes you suggested and in the meantime I leave you feedback

rm -rf should work with a list of directories and folders. Add debug nodes to all outputs of the exec node and check for errors. Set the debug nodes to output complete message. Does the node-red user have permission to delete the files/folders?

I followed your suggestions and tried it like this:

  • The "DEL test" button has no property defined (I don't know if it's supposed to set something in the "when clicked send:..." option).
  • The first change node moves the array object (I copied the path of the line referring to the rowSelection as the image below, which is where the array with the different filenames is)
    image
  • On split node I don't know what properties it should be configured with
  • On the last change node I move "msg.payload.filename" to "msg.payload" and feed the fs-ops-delete node.
  • On fs-ops-delete node I have the path of the RPi where the files are and on "Filename" I have msg.payload

With this attempt nothing happens, I select for example 2 files, click on the button and nothing happens. The debug node "set" returns "undefined" when I click the DEL button.

Yes as I told you above I tested the delete through "rm -rf" and it works for files or directories.

That's why I remembered the for loop or forEach that ran the command for each array[i] (each position of the array would serve to add the name of each selected file to the end of the command), but I don't know how to use it here :frowning:

What are you seeing in the first debug node? The payload should be the contents of the rowSelection array.
The default Split node setting should be ok.
Then the second debug should be multiple messages each with one element of the array.
Then add a third debug after the second Change to make sure you get multiple messages, each with just the file name.

Start from the beginning and get it working at each point down the line. I advise disconnecting the Delete node till you know you are sending it the right information. Otherwise you might find yourself deleting anything and everything.

With everything set up like this:

  • 1st debug node (named move_array) selected to show only msg.payload shows "undefined" and select to complete object shows a strange object not related with what we are expect (image below)
    image

-2nd and 3rd debug nodes show nothing at all