ForEach item loop variable usage in expression
What seems off:
ForEach state defines an iterationParam "The iterationParam property defines the name of the iteration parameter passed to each iteration of the ForEach state. It should contain the unique element of the inputCollection array and made available to actions of the ForEach state."
This parameter can be used in expressions. as illustrated in the spec example
"name":"SendConfirmState",
"type":"foreach",
"inputCollection": "${ [.orders[] | select(.completed == true)] }",
"iterationParam": "completedorder",
"outputCollection": "${ .confirmationresults }",
"actions":[
{
"functionRef": {
"refName": "sendConfirmationFunction",
"arguments": {
"orderNumber": "${ .completedorder.orderNumber }",
"email": "${ .completedorder.email }"
}
}
}],
We can see that the completedOrder iterationParam is accessed using JQ syntax for accessing properties in the workflow model, a "." prefix, as if the iterationParam were part of the workflow model, when in reality it is not and it should not be. It would better if the iterationParam is considered a JQ variable and accessed using $ rather than .
What you expected to be: I expected the iterationPram to be accessed using $ rather than ., since $ is the reserved word in jq for accessing scope variables. Therefore, the example should look like
"name":"SendConfirmState", "type":"foreach", "inputCollection": "${ [.orders[] | select(.completed == true)] }", "iterationParam": "completedorder", "outputCollection": "${ .confirmationresults }", "actions":[ { "functionRef": { "refName": "sendConfirmationFunction", "arguments": { "orderNumber": "${ $completedorder.orderNumber }", "email": "${ $completedorder.email }" } } }],
Anything else we need to know?: See JQ spec for more details
Environment: This is not related with any enviroment.
- Specification version used:
- 0.8
+1000 Very good point! To work around that, in Synapse I had to inject the iteration param into the state data, then invoke the action pipeline, then prune it out. What you are proposing is IMO an elegant solution to avoid mixups.
@cdavernas yes, I had to do the same ;). and this is indeed a hack which have other implementation consequences. For example, not able to perform evaluation in multiple threads because the model is temporarily changed for that evaluation. The alternative, cloning it before adding, is too problematic from a performance point of view (will work only for small models)
Very good point indeed. Go ahead and open a PR. I think we have a strong argument based on JQ spec.
The only caveat is for other languages, like jsonpath. We should add a note there that for jq, we access it using $.
In JsonPath the equivalent for JQ $ I believe is @ We can not say anything and just update the existing example for JQ or state the issue in the text. https://github.com/serverlessworkflow/specification/pull/683
@fjtirado Shouldn't that issue be closed, as it was merged by #683?