Test a property of an array of objects

I have an array of objects.

I want to test a specific property of each object. If one test fails, the whole array fails and I want a single 'failed' output.

I can do this in a Javascript function but cannot work out how to do it using nodes.

I can split the array and test each element but that gives me multiple 'fails'.

Suggestions?

Take array length before splitting and store to flow variable.
Do validation, pass through only valid results, then join.
Compare array length with flow variable. If they are equal, result is valid.

[{"id":"2ee6ff33.d66e7","type":"inject","z":"f56ccabd.7567e8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":580,"wires":[["eb4ab40e.b2b0f8"]]},{"id":"eb4ab40e.b2b0f8","type":"function","z":"f56ccabd.7567e8","name":"correct","func":"var arr = []\nfor(var i=0;i<5;i++){\n    var o = {id:i,param:i*2}\n    arr.push(o)\n}\nmsg.payload = arr\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":340,"y":580,"wires":[["fc218f58.360fe"]]},{"id":"74302180.a966b","type":"function","z":"f56ccabd.7567e8","name":"wrong","func":"var arr = []\nfor(var i=0;i<5;i++){\n    var o = {id:i,param:i*2}\n    arr.push(o)\n}\narr[3].param = \"wrong\"\nmsg.payload = arr\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":340,"y":620,"wires":[["fc218f58.360fe"]]},{"id":"e0d529fa.3ff2b8","type":"inject","z":"f56ccabd.7567e8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":170,"y":620,"wires":[["74302180.a966b"]]},{"id":"f4e29903.4ea1d8","type":"split","z":"f56ccabd.7567e8","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":370,"y":480,"wires":[["740f558f.abcd3c"]]},{"id":"740f558f.abcd3c","type":"switch","z":"f56ccabd.7567e8","name":"","property":"payload.param","propertyType":"msg","rules":[{"t":"istype","v":"number","vt":"number"},{"t":"lt","v":"10","vt":"num"}],"checkall":"true","repair":true,"outputs":2,"x":490,"y":480,"wires":[[],["e02e217.58589e","fd7038f8.dc51e8"]]},{"id":"fd7038f8.dc51e8","type":"join","z":"f56ccabd.7567e8","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":610,"y":440,"wires":[["a968089e.314e58"]]},{"id":"447c4784.e6cb68","type":"debug","z":"f56ccabd.7567e8","name":"CORRECT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":440,"wires":[]},{"id":"fc218f58.360fe","type":"change","z":"f56ccabd.7567e8","name":"","rules":[{"t":"set","p":"count","pt":"flow","to":"$count(payload)\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":480,"wires":[["f4e29903.4ea1d8"]]},{"id":"a968089e.314e58","type":"switch","z":"f56ccabd.7567e8","name":"","property":"$count(payload)\t","propertyType":"jsonata","rules":[{"t":"eq","v":"count","vt":"flow"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":730,"y":480,"wires":[["447c4784.e6cb68"],["2a788523.1638ca"]]},{"id":"2a788523.1638ca","type":"debug","z":"f56ccabd.7567e8","name":"WRONG","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":520,"wires":[]},{"id":"e02e217.58589e","type":"debug","z":"f56ccabd.7567e8","name":"SECOND","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":560,"wires":[]},{"id":"6de4570e.8cbf18","type":"function","z":"f56ccabd.7567e8","name":"wrong","func":"var arr = []\nfor(var i=0;i<5;i++){\n    var o = {id:i,param:i*2}\n    arr.push(o)\n}\narr[3].param = 12\narr[2].param = \"wrong type\"\nmsg.payload = arr\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":330,"y":680,"wires":[["fc218f58.360fe"]]},{"id":"5337a04c.2e57b","type":"inject","z":"f56ccabd.7567e8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":680,"wires":[["6de4570e.8cbf18"]]}]

EDIT: for multiple condition check, take result from last output and be sure, the checking all rules option is in use.

Trick is to use the sequence recreation, so the joining can be done.

Thanks.

Am I right that you can only check one property of an object at one time? Multiple properties (an AND) is multiple switch nodes?

I think so. For multiple properties and more complex validation I'd preferred to do it with function node.

1 Like

You could us JSONata expression in switch node to test multiple properties

@E1cid Interesting you suggest this, I just tried it and although - in the switch - using jsonata - the test option works, it doesn't work. I'm about to open a thread on this very issue with an example.

I'll update this thread with a link as soon as I do.

CORRECTION It is possible!! You use the JSONata exp
Screen Shot 2021-03-13 at 5.15.38 AM

Here is a test flow showing it in action:

[{"id":"bcbbf688.15a69","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"7c49307d.9db75","type":"inject","z":"bcbbf688.15a69","name":"dog - brown","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"animal\":\"dog\",\"color\":\"brown\"}","payloadType":"json","x":110,"y":80,"wires":[["322078ba.9084b","a0f00437.ba40d"]]},{"id":"be457815.099aa","type":"inject","z":"bcbbf688.15a69","name":"dog - black","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"animal\":\"dog\",\"color\":\"black\"}","payloadType":"json","x":110,"y":140,"wires":[["322078ba.9084b","a0f00437.ba40d"]]},{"id":"6b0b4f8f.932e18","type":"debug","z":"bcbbf688.15a69","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":160,"wires":[]},{"id":"322078ba.9084b","type":"switch","z":"bcbbf688.15a69","name":"jsonata: (payload.animal = \"dog\") and (payload.color = \"black\")","property":"payload","propertyType":"msg","rules":[{"t":"jsonata_exp","v":"(payload.animal = \"dog\") and (payload.color = \"black\")","vt":"jsonata"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":410,"y":220,"wires":[["6b0b4f8f.932e18"],["171a99f5.daa6be"]]},{"id":"a0f00437.ba40d","type":"debug","z":"bcbbf688.15a69","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":350,"y":60,"wires":[]},{"id":"171a99f5.daa6be","type":"debug","z":"bcbbf688.15a69","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":280,"wires":[]},{"id":"b90434be.4bd2e","type":"catch","z":"bcbbf688.15a69","name":"","scope":null,"uncaught":false,"x":250,"y":320,"wires":[["490ff05a.d5eb38"]]},{"id":"490ff05a.d5eb38","type":"debug","z":"bcbbf688.15a69","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":470,"y":320,"wires":[]}]

Hi @borpin there are times when a function node is the just the right best way to go with certain things. Consider you can easily solve this with one function node vs multiple standard nodes & a whole bunch of tricks. I would personally recommend sticking with a function node for this.

2 Likes

I would add you may need to check type as the expression will throw an error when you try to compare stings and numbers.

$type(payload.param)="number" ?	(payload.param < 10 and payload.id < 6) : false

without type() if param is string jsonata will give error.

1 Like

Indeed. The function node IS a standard node and is there to be used just as much as any other.

3 Likes

Thanks everyone, I just wondered if there was an easier way than a function.

I ended up with a function :slight_smile:

msg.payload = msg.data.filter(function(data){
    return (data.attributes.device_class == "temperature") && ((data.attributes.last_median_of < 5) || (Date.parse(data.last_updated) + 300000) < Date.now());
}).length > 0;

I would have done it like this

[{"id":"bca1a0bc.8bf72","type":"inject","z":"1d254cc8.5925b3","name":"black dog","topic":"","payload":"{\"animal\":\"dog\",\"color\":\"black\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":380,"wires":[["f2fe6b6.ad16f98"]]},{"id":"f2fe6b6.ad16f98","type":"switch","z":"1d254cc8.5925b3","name":"animal=dog","property":"payload.animal","propertyType":"msg","rules":[{"t":"eq","v":"dog","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":380,"wires":[["b2dd4ee8.3dda"],["bef458a1.54af48"]]},{"id":"b2dd4ee8.3dda","type":"switch","z":"1d254cc8.5925b3","name":"color=black","property":"payload.color","propertyType":"msg","rules":[{"t":"eq","v":"black","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":490,"y":380,"wires":[["c6c68a0c.9ed648"],["bef458a1.54af48"]]},{"id":"c6c68a0c.9ed648","type":"debug","z":"1d254cc8.5925b3","name":"black dogs","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":670,"y":380,"wires":[]},{"id":"bef458a1.54af48","type":"debug","z":"1d254cc8.5925b3","name":"otherwise","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":660,"y":420,"wires":[]},{"id":"a3b77595.904bf8","type":"inject","z":"1d254cc8.5925b3","name":"gray cat","topic":"","payload":"{\"animal\":\"cat\",\"color\":\"gray\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":420,"wires":[["f2fe6b6.ad16f98"]]}]

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