Using object keys: alternatives to this code?

Hi all, I'd like to do this with nodes, rather than using a JS function node.

Why? Because it's much easier for non-programmers to understand the flow than the JS :slight_smile:

Essentially, I am using a known key, stored in flow.foo, to extract the data from an object flow.barof this structure:

{
        "itemA": {
            "amount": "20",
            "type": "hamper"
        },
        "itemB": {
            "amount": "22"
            "type": "box"
}

Currently I have this JS in a Function node.

var foo = flow.get("foo");
var bar = flow.get("bar");
msg.payload = bar[foo];
return msg;

So assuming flow.foo = "Item A"
msg.payload will return:

{
    "payload": {
        "amount": "20",
        "type": "hamper"
    }
}

Originally I had tried many variants on a change node like this... but no luck:

53

Any help appreciated!

With your Change node, if you change the type of the "to" field to Expression, you can use:

$lookup($flowContext("bar"), $flowContext("foo"))

Whether that is any more readable then the Function code is going to be subjective.

Ah! I knew Andrew would have put in some way to do it in Jsonata :slightly_smiling_face:

It is probably slightly more readable, IMO, yes.

Would you mind me asking why what I attempted to do is not possible?

flow.bar[flow.foo]

I suspect the answer is that JS doesn’t work like that... but my question is really, why doesn’t it work like that? It feels like a reasonable syntactic choice!

(TBH flow.bar.flow.foo or flow.bar(flow.foo) feels even better, but probably good reasons they aren’t good!)

And btw, just to say here publicly:

Node Red, awesome. My personal thanks to you for your amazing work these past few years. Hugely appreciated!

1 Like

Who’s Andrew ? :wink:

The 'flow' input type simply doesn't support that type of self reference when evaluating a property name.

Sorry Andrew Coleman is the guy who wrote Jsonata! Awesome individual. It is so useful!

:slight_smile:

1 Like

Well it's all down to context again (in the wider programming sense). If there was an object called flow that was accessible then yes you could do that... in fact if you had it all stored on the msg then you could have. As flow. (and global.) have to be special (so flow properties are indeed per flow (or subflow)), then they are not simple objects so flow.bar is not the same as flow.get("bar") . The reason for using .get and .set is so that these methods can be extended to external storage for persistence.

Ahh! Now that makes sense! I knew there had to be a reason! Thank you :slight_smile: