TomFrost / Jexl

Javascript Expression Language: Powerful context-based expression parser and evaluator
MIT License
561 stars 92 forks source link

With addUnaryOp, evalSync evaluation differs from asynchronous eval #61

Closed ChabotPierreAlain closed 5 years ago

ChabotPierreAlain commented 5 years ago

I used addUnaryOp to return the length of a filtered array :

jexl.addUnaryOp("length", array => { if (Array.isArray(array)) { return array.length; } return 0; });

When I build an expression like :

length objects[.myProperty in ["A","B"]]

Let's say I got this object to evaluate:

{ "objects": [ {"myProperty":"A"},{"myProperty":"B"},{"myProperty":"C"} ] }

The eval method will return 2 as result, but evalSync will evaluates the same expression to 3. It seems like the filtering part on the array vs my custom "length" are not executed with the same operation priorities depending if I use eval or evalSync.

TomFrost commented 5 years ago

I'm looking at this right now -- my hope was that the changes in the today's 2.2.0 release would correct this since it contained other bugfixes for PromiseSync, but I've confirmed your report even on the new version. This works great under eval, but not evalSync. Very strange! I will continue digging.

TomFrost commented 5 years ago

Turns out the issue here isn't in the unary operator, it's in the collection filter expression. That particular piece was being evaluated asynchronously even when evalSync was called. I've fixed this in 2.2.1, published just a second ago. Thanks for the catch!