How to loop over msg.payload.states as array of objects

I have an msg object that has sub array's of objects.

How can I add an element in to the objects?

This is my data: pastebin link

The problem is that every time I try to work with msg.payload.portstates (an array of objects in the object) I get errors. I tried a load of loop possibilities like .foreach, for.. in, map, spread operator, but all fails.

My goal i to add the msg.payload.ts (timestamp) in to all the msg.payload.portstates[0-7] as msg.payload.portstates[0].ts

In a function node, you can modify the sub-array objects, like this:

msg.payload.portstates.forEach(obj => obj.ts = msg.payload.ts);
return msg;

Of course, this includes NO CHECKING that the payload has a ts field or value, and it assumes that portstates is an array of objects... but you get the idea.

try

msg.payload.portstates = msg.payload.portstates.map(obj => Object.assign(obj, {ts: msg.payload.ts}));
return msg;

@shrickus your code would return an array of timestamps, you would need to do

msg.payload.portstates = msg.payload.portstates.map(obj => {
    obj.ts = msg.payload.ts
    return obj;
    }
);
return msg;

Array.forEach( ... ) allows me to modify each object in-place... so no need to create a new array or clone any of its objects.

Sorry miss read, did not see forEach , my eyes saw map, doh.

If you are not comfortable with JavaScript functions, the low code version is split -> change -> join

[{"id":"60f6d31fcf25324f","type":"inject","z":"fc65972c8d3b1d68","name":"","props":[{"p":"ts","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":650,"y":760,"wires":[["27dc35d881e29dfc"]]},{"id":"27dc35d881e29dfc","type":"function","z":"fc65972c8d3b1d68","name":"demo data","func":"\nreturn {\n    \"topic\": \"telemetry\",\n    \"payload\": {\n        \"type\": \"telemetry\",\n        \"portstates\": [\n            {\n                \"port\": \"1\",\n                \"name\": \"M1 Ab\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"2\",\n                \"name\": \"M1 Auf\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"3\",\n                \"name\": \"M2 Ab\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"4\",\n                \"name\": \"M2 Auf\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"5\",\n                \"name\": \"Putzlicht aktiv\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"6\",\n                \"name\": \"Putzlicht Toggl\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"7\",\n                \"name\": \"Output Port\",\n                \"state\": 0\n            },\n            {\n                \"port\": \"8\",\n                \"name\": \"Output Port\",\n                \"state\": 1\n            }\n        ],\n        \"inputstates\": [\n            {\n                \"idx\": 1,\n                \"name\": \"EVAK\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 2,\n                \"name\": \"Putzlicht Status\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 3,\n                \"name\": \"Input\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 4,\n                \"name\": \"Input\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 5,\n                \"name\": \"Input\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 6,\n                \"name\": \"Input\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 7,\n                \"name\": \"Input\",\n                \"state\": 1\n            },\n            {\n                \"idx\": 8,\n                \"name\": \"Input\",\n                \"state\": 0\n            }\n        ],\n        \"ts\": 1661189762\n    },\n    \"qos\": 1,\n    \"retain\": false,\n    \"_msgid\": \"ddf24fa0ad0328c6\",\n    \"mqtt\": \"gpio/gpio1/device/telemetry\",\n    \"cathegory\": \"gpio\",\n    \"device\": \"gpio1\"\n};","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":760,"wires":[["9a8b3997691ba5aa"]]},{"id":"5c4785435ee998b2","type":"split","z":"fc65972c8d3b1d68","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":810,"y":840,"wires":[["2156f99e74f91ed0"]]},{"id":"9a8b3997691ba5aa","type":"change","z":"fc65972c8d3b1d68","name":"","rules":[{"t":"set","p":"ts","pt":"msg","to":"payload.ts","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.portstates","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":840,"wires":[["5c4785435ee998b2"]]},{"id":"2156f99e74f91ed0","type":"change","z":"fc65972c8d3b1d68","name":"","rules":[{"t":"set","p":"payload.ts","pt":"msg","to":"ts","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":970,"y":840,"wires":[["da8b4b3454c90b6f"]]},{"id":"da8b4b3454c90b6f","type":"join","z":"fc65972c8d3b1d68","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":1130,"y":840,"wires":[["3ef927e56718546d"]]},{"id":"3ef927e56718546d","type":"debug","z":"fc65972c8d3b1d68","name":"debug 64","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1120,"y":900,"wires":[]}]

"TypeError: Cannot read properties of undefined (reading 'forEach')"

Why does my code say that?

=> it turns out the input was an string not json. I had to parse it to json first. (of coarse! it's MQTT...)

Thanks @Steve-Mcl for the detailed testing!

the MQTT node can be set to parse the object for you...