Evaluating Expressions via the API
Summary
- AdapTableQL can evaluate an Expression as an explicit call — no Module has to own it
- Use it when you want the same engine as Grid Filter, Alerts and Calculated Columns, but from your own code
- There are 4 methods available to meet all potential use cases and the types of Expressions AdapTable offers
AdapTable typically evaluates an Expression in response to an event in the UI.
For example when running a Grid Filter, calculating a Calculated Column value, or rendering a Cell with a Conditional Style, AdapTable will hand over the evaluation to AdapTableQL which will return the result.
However it is possible to leverage AdapTableQL programmatically - to evaluate an Expression entirely via the API.
Note
- This is one of 2 ways in which an Expression is evaluated outside the UI
- The other is Server Evaluation when you will evaluate Expressions on your server
const result = adaptableApi.expressionApi.evaluateStandardExpression({
expression: '[price] * [qty] > 1000',
primaryKeyValue: 42,
});
if (result.success) {
console.log(result.value); // true | false
} else {
console.warn(result.errorMessage);
}Important
- AdapTableQL still evaluates the Expression
- The difference is that you ask for the result yourself, instead of hanging it off a Grid Filter, Calculated Column etc.
Why evaluate via API
There are many potential use cases where you might want to evaluate an Expression using the API.
For instance you might want to:
- ask a question once (“does this row pass?”, “what is this value?”) outside of a Module
- drive your own UI — a toolbar button or custom form — from an Expression the user typed or you shipped
- run a what-if: would this row still match if
pricewere 120? - filter your own array of rows, not the grid
Note
- The Expression string is the same one you would put in Initial State or the Expression Editor
- AdapTableQL evaluates it exactly the same way as it would evaluate if invoked by AdapTable's UI
API Methods
AdapTable provides 4 Expression-evaluation methods in Expression API:
evaluateStandardExpressionevaluateAggregatedExpressionfilterRowNodesfilterDataSet
These are designed to be able to meet a range of potential use cases:
| You want | Call |
|---|---|
a true / false result | evaluateStandardExpression |
| a value for one row | evaluateStandardExpression |
| the rows that match | filterRowNodes or filterDataSet |
a snapshot (SUM, AVG, GROUP_BY, RANK, …) | evaluateAggregatedExpression |
evaluateStandardExpression
Use this function to evaluate a Standard Expression against a single row.
The Expression determines the return value: a boolean condition will yields true / false, while a value Expression will yield that value.
evaluateStandardExpression
request: EvaluateStandardExpressionRequestExpressionEvaluationResult<unknown>Hint
- If you are looping
evaluateStandardExpressionover every row, usefilterRowNodes/filterDataSetinstead - Validation runs once, and matching rows keep their source order and object identity
evaluateAggregatedExpression
Use this function to evaluate an Aggregation Expression over a set of rows (the grid, a narrowed subset, or an array you supply).
It returns a snapshot of the result — the aggregated value, any GROUP_BY breakdown, and a per-row projection.
When the Expression is a condition, you also get whether it matches.
evaluateAggregatedExpression
request: EvaluateAggregatedExpressionRequestExpressionEvaluationResult<AggregatedExpressionEvaluationValue>Observable Expressions
There is no API method to subscribe to an Observable Expression.
Note
evaluateStandardExpressioncan evaluate an Observable Expression (e.g.HIGHEST{[price], WITHIN(1h)}) against a grid row, returning its current value- Observable Expressions are grid-only, so passing
dataordataSetis rejected
To react live to an Observable pattern, create an Observable Alert and listen to the Alert Fired Event, or display the value in an Observable Calculated Column.
filterRowNodes
Use this function to return the grid rows that match a boolean Expression.
It evaluates the Expression once per row and returns the matching IRowNodes in source order.
filterRowNodes
request: FilterRowNodesRequestExpressionEvaluationResult<IRowNode[]>filterDataSet
Use this function to filter an array of your own rows with a boolean Expression.
Same behaviour as filterRowNodes, but the input and output are your objects rather than grid row nodes.
filterDataSet
request: FilterDataSetRequestExpressionEvaluationResult<Record<string, unknown>[]>- The
EvaluateToolbar has 4 buttons; each calls one method and shows the result in the System Status:- Large Open Trades -
filterRowNodeswith[notional] > 75000 AND [status] = 'Open' - What If Price +10% -
evaluateStandardExpressionon trade 1, with and without acellValueOverrideraising its Price by 10% - Check Proposed Orders -
filterDataSetover an array of orders which are not in the grid - P&L by Desk -
evaluateAggregatedExpressionwithSUM{[pnl], GROUP_BY([desk])}, readinggroupValues
- Large Open Trades -
- Click each button and read the result in the System Status
- Change trade 1's
StatustoClosedand click Large Open Trades again - Change a
P&Lvalue and click P&L by Desk - the snapshot is recalculated on each call
The rest of ExpressionApi is supporting: isValid* before you evaluate, getColumnsFromExpression, getASTForExpression (also used by Server Evaluation).
Function Results
Synchronous evaluate / filter methods never throw for expected input errors (typos, unknown columns, missing row, unavailable functions).
type ExpressionEvaluationResult<T> =
| {success: true; value: T}
| {success: false; errorMessage: string};Always check success before reading value.
The Expression decides what value is.
A condition such as [price] > 100 yields true / false. [price] * 1.19 yields a number.
Deep Dive
Evaluating your own data
Caution
- There are a number of "Gotchas" that you need to be aware of when evaluating Expressions via the API:
- Check
success. The API does not throw for bad Expressions or missing rows - This is not Server Evaluation.
evaluateAdaptableQLExternallydoes not apply here - One row target for
evaluateStandardExpression. Pass exactly one ofrowNode,primaryKeyValueordata $SCOPEand Relative Change need extra context. ProvidecolumnScope/dataChangedEventor evaluation failsmodulechanges the function pool. Default is every function. Pass Module name to see what that Module allows- Aggregations are snapshots. Re-evaluate if you need them to track the grid. Read
matcheswhen the Expression is a condition - SSRM aggregations are partial. Use
rowCount - Observables cannot use
data/dataSet, and cannot be subscribed to via the API - Filter helpers fail the whole call if any row errors
- Check
FAQ
Can I use the API to evaluate an Expression that lives in a Module?
Yes, read the Rule / Query string from State and pass it to the matching evaluate* / filter* method
Can I evaluate against rows that are not in the grid?
Yes, pass data (one row) or dataSet (many rows). Remember that valueGetters will not run
Does this replace Grid Filter?
No, Grid Filter still owns what the user sees.
Use filterRowNodes when your code needs the matching rows.