Jsonata expressions from a separate file?

Hi,

We are using jsonata expressions in node-red a lot together with git repos stored in github. Would it be possible to have the jsonata expression available in an external file within the project instead of just have the expression inline in the node itself?
Here is an example of what I mean from another integration tool (will not mention any names :wink: ).
image

I think it would make life easier when we want to track what happened to our expressions in git? Just a suggestion.

Hi @jonasolsson83 - welcome to the forums.

I'm not sure what you mean, JSONata is used in Node RED Core Nodes for single properties, are you using a Node that is for evaluating JSONata expressions only?

if so, you will need to request that from the Node author.

Sorry, but I'm not sure i follow

Sorry I might have been a bit unclear. Hopefully this example could explain it better?

So basically what I'm doing is that I'm using a http in node, transforming the data to another format and then reply with the new data format (this was just an example). So what I would like to do is to store the jsonata expression (mapping) that I have created in a separate file, and not in the change node (flows.json) as it is now. Are you following?

Right,

That will be a significant piece of work to the core, as it will require another typedInput type.
the J: is currently in-line, so to use external expressions, will require dreaming up a new J: type.

such as eJ: for example.

I wouldn't count on this being developed anytime soon, as there are other priorities on the list.

With that said, I have moved this into Feature Requests, as the Core Team may have input into such a feature

Totally understandable, Feature requests sounds good. Thank you for quick reply!

And again, why I asking is because when doing changes to the mapping code it will be easier to track changes in any external git comparing tools instead of comparing the whole flows.json.

1 Like

As an alternative, JSONata is available in function nodes as well so you could have the actual code in an external library.

1 Like

Coupled with the file read node - Bada Bing Bada Boom :sunglasses:

I was actually thinking that they could use an actual node.js module file attached to settings.js global

I was going with:

File Read Node ("Expression.json") -> Function Node (declare JSONata lib module) -> Evaluate.
but that could get messy i think

Assuming you mean declaring JSONata as a module in a function node - or have I missed some magic I'm not aware of?

No, a node.js module can be a simple JSON object. so you could have something like:

export {
  "expr1": "$random();",
  "expr2": "{\"thisthing\": payload}",
  // etc
}

In the globals in settings.js:

    myjsonataexpressions: require('./jsonataexpr.js')

And then you can global.get the library in a function node.

You didn't expect something simple from me did you! :rofl:

But, if you need to manage the expressions in github, this is a potentially good way to go.

1 Like

I can do better

export {
  "expr1": require("expression1.json"),
  "expr2": require("expression2.json"),
  // etc
}

:wink:

I'll stop as this will get out of hand :joy:

Should be possible using a function node or create a custon node to read a file and

prepareJSONataExpression

evaluateJSONataExpression

Or store your expressions in context and use $eval() to to run the expressions.

2 Likes

I have just this minute found out.

  • RED.util.prepareJSONataExpression.
  • RED.util.evaluateJSONataExpression

are available for use in function Nodes.

image

As they say, every day is a school day!

@jonasolsson83 as suggested by @E1cid

Use a File Read Node - to load your expressions file.
then use the content in a function node, to evaluate the expression (methods above)

const Expr = RED.util.prepareJSONataExpression(<Expression-String-From-File>, node)
RED.util.evaluateJSONataExpression(Expr, msg, (err, value) => {
    node.send({payload:value})
})
2 Likes

I believe I pointed that out earlier.

Yup - but I thought via using the lib as a global or declared in the function.

I didn’t know it was already exposed via util :face_with_peeking_eye:

1 Like

thank you so much for your replies on this :slight_smile: I will try that!

1 Like

You might want to devise a method of first loading your file(s) contents into a context variable on Flow start, and call into it for each execution.

else you could end up with high IO Read rates on the disc

const Expr = RED.util.prepareJSONataExpression(global.get("Expressions").someNamedExpression, node)
RED.util.evaluateJSONataExpression(Expr, msg, (err, value) => {
    node.send({payload:value})
})

Its pretty much what @TotallyInformation suggested, but doing it on load, should remove the need to mess with the settings file, and will allow easy updates to expressions requiring only a Node RED restart - but then you could also add an inject node to reload the files removing the need for a restart all together


Mods: I moved this into FR's but clearly this seems a lot less intrusive to the core, feel free to move it away from FR's, if you feel its not worth pursuing

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