Filter Transform
The filter request transform allows authors to take a filter criterion and turn into a filter query that is generally appended to the configuration.url
.
The filter criterion provided via the options
parameter is an object that has a single attribute filter criterion with properties { op, attribute, value }, or more complex criterion as defined by the JET Data Provider docs. Additionally, text filtering is also supported (similar to the JET TextFilterDef).
While the JET Data Provider Filter API defines many complex structures for representing a filter criterion only a subset of these definitions and capabilities are implemented by the Business Object based service transforms implementation.
The Business Objects transforms supports transforming filter criterion that use a simple form (similar to JET AttributeExprFilterDef - refer to the JET docs for details), or a compound filter that is an array of simple attribute filter criterion. Nested criterion structures as shown below are also supported. See examples shown below
When using an SDP also refer to the docs for the same on how filterCriterion
property is configured.
Examples of Criterion Transforms
This example is a simple attribute criterion that transforms to "q=empName = 'Lucy'"
:
{
"op": "$eq",
"attribute": "empName",
"value": "Lucy"
}
This example is a compound criterion that tranforms to "q=hireDate > '2015-01-01' or hireDate <= '2018-01-01'"
:
{
"op": "$or",
"criteria": [
{
"op": "$gt",
"attribute": "hireDate",
"value": "2015-01-01"
},
{
"op": "$le",
"attribute": "hireDate",
"value": "2018-01-01"
}
]
}
This example is a nested compound criterion that transforms to the following query parameter "q=((foo LIKE 'foo%') and ((bar >= 'bar1') or (bar <= 'bar2')))"
:
{
"op": "$or",
"criteria": [
{
"op": "$and",
"criteria": [
{
"attribute": "price",
"op": "$gt",
"value": 30
},
{
"attribute": "price",
"op": "$lt",
"value": 40
}
]
}
]
}
This is an example of text filtering that transforms to q=(PartyName LIKE 'Megha%')
. The term 'PartyName' is picked up by automatically looking up a special property on the transformsContext property - vb-textFilterAttributes: ['PartyName']
. If nothing is set then the keyAttribute is used as the attribute for the text search:
{
"text": "Megha"
}
This is an example of text filtering that is combined with compound criterion that transforms to q=((PartyName LIKE 'Megha%') and (Foo = 'bar1'))',
":
{
"op": "$and",
"criteria": [
{
"text": "Megha"
},
{
"op": "$or",
"criteria": [
{
"op": "$eq",
"attribute": "Foo",
"value": "bar1"
}
]
}
]
}
For 3rd party services the author can provide a custom filter transforms implementation.
Signature
The filter transform function can be declared like this:
const filter = function(configuration, options, transformsContext) {
var c = configuration;
// use the filter criterion provided on 'options' parameter to generate the filter query
// update c.url as needed
return c;
}
This function has the following parameters:
configuration
an object with the following properties:- Refer to the signature in Request Transformation Functions for details on the various properties.
options
the filter criterion to transform. Business Objects transforms supports the following compound and attribute operators in the filter criterion:'$co', // see JET AttributeFilterOperator.AttributeOperator.$co '$eq', // see JET AttributeFilterOperator.AttributeOperator.$eq '$ew', // see JET AttributeFilterOperator.AttributeOperator.$ew '$pr', // see JET AttributeFilterOperator.AttributeOperator.$pr '$gt', // see JET AttributeFilterOperator.AttributeOperator.$gt '$ge', // see JET AttributeFilterOperator.AttributeOperator.$ge '$lt', // see JET AttributeFilterOperator.AttributeOperator.$lt '$le', // see JET AttributeFilterOperator.AttributeOperator.$le '$ne', // see JET AttributeFilterOperator.AttributeOperator.$ne '$sw', // see JET AttributeFilterOperator.AttributeOperator.$sw '$and', // see JET CompoundFilterOperator.CompoundOperator.$and '$or', // see JET CompoundFilterOperator.CompoundOperator.$or ]
transformsContext
is an object that is set by the author (ServiceDataProvider, RestHelper, Call Rest action) to then be passed as is to all transforms for the current fetch cycle.
The function returns the updated configuration
object.
Usages
The examples below illustrate the arguments passed to the filter transform as well as the effect its code has on the fetch performed by the RestHelper.
The examples below use a service fixitfast
that has a GET endpoint to retrieve the list of customers.
Example 1-9 ServiceDataProvider variable
Assume that the following variable of type vb/ServiceDataProvider is defined in a page that refers to the above GET /customers endpoint. The SDP variable includes a default filter criterion and also sets a property called transformsContext
with a key vb-textFilterAttributes
that is set to ['lastName']
. This is a hint to the filter request transform to use this attribute when building a text query.
{
"variables": {
"customersSDP": {
"type": "vb/ServiceDataProvider",
"defaultValue": {
"endpoint": "fixitfast-service/getCustomers",
"keyAttributes": "id",
"itemsPath": "result",
"responseType": {
"result": "customerResponse[]"
},
"filterCriterion": {
"op": "$eq",
"attribute": "region",
"value": "{{ $variables.customer.region || \"US\" }}"
},
"transformsContext": {
"vb-textFilterAttributes": ["lastName"]
}
}
}
}
}
When a caller such as a component bound to the above SDP initiates a fetch call, it can also provide additional filter criterion along with a text value to search against if applicable (example oj-select-single provides a text filter in the form { text: '<some-text-to-search>' }
). These are combined with the configured filter criterion above and the merged filter criterion is provided to the filter transforms function. Refer to the Service Data Provider docs for details.
The filter request transforms function uses the filter criterion passed in via the options parameter to build a query param on the configuration url.
The filter
transform is implemented in the service transforms as follows:
define([], function () {
class Request {
static filter(configuration, options, transformsContext) {
const c = configuration;
const tc = transformsContext;
const textFilterAttributes = tc && tc[VB_TEXT_FILTER_ATTRS];
// process options to build the query
return c;
}
}
class Response {};
class Metadata {};
// Note: as an example, the Request object is expanded to include just the filter property
return {
metadata: Metadata,
request: { filter: Request.filter },
response: Response
};
});
Example 1-10 Rest Action
Assume that the following variable of type vb/ServiceDataProvider is defined in a page that delegates the fetch to an action chain (set via 'fetchChainId'
property).
The chain "fetchCustomersChain"
in its fetchCustomers
RestAction configuration sets a default filter criteria via the property requestTransformOptions.filter
.
When a fetch is initiated by a component bound to the SDP, the filter criterion is automatically passed in to the filter
transform function associated to the service, along with the ones provided by caller, via the options
parameter. Refer to the Call Rest action docs for details.
{
"variables": {
"customersSDP": {
"type": "vb/ServiceDataProvider",
"defaultValue": {
"fetchChainId": "fetchCustomersChain",
"keyAttributes": "id",
"itemsPath": "result"
}
}
},
"chains": {
"fetchCustomersChain": {
"variables": {
"configuration": {
"type": {
"hookHandler": "vb/RestHookHandler"
},
"description": "the configuration for the rest action",
"input": "fromCaller",
"required": true
}
},
"root": "fetchCustomers",
"actions": {
"fetchCustomers": {
"module": "vb/action/builtin/restAction",
"parameters": {
"endpoint": "fixitfast-service/getCustomers",
"hookHandler": "{{ $variables.configuration.hookHandler }}",
"responseType": "customersComputedResponse",
"requestTransformOptions": {
"filter": {
"op": "$eq",
"attribute": "region",
"value": "{{ $page.variables.customer.region || \"US\" }}"
}
}
},
"outcomes": {
"success": "returnCustomersResponse",
"failure": "returnFailureResponse"
}
}
}
}
}
}
Write a Filter Transforms Function for Text Filtering
If your SDP binds to a business object REST API endpoint, you have the following options to get text filtering to work:
- Option 1: Configure the SDP to include a vb-textFilterAttributes property where the attributes to apply the text filter is specified. The built-in business object REST API transforms look for this property and automatically build a filter criterion using the text and turns it into a 'q' param.
"transformsContext": { "vb-textFilterAttributes": ["lastName"] }
For the above configuration example, if a user enters text 'foo' in select-single, the SDP generates
q=lastName LIKE 'foo%'
.By default, the operator used is 'startsWith' as this is considered to be more optimized for db queries than 'contains'.
- Option 2: If Option 1 doesn't meet your needs, then you can write a custom filter transform that massages the text filter and turns it into a regular filterCriterion.
If you use option 2, you could do something similar to the following example. In this example, resourcesListSDP uses the getall_resources endpoint. The (request) filter transforms property is a callback that is defined in the PageModule.
"resourcesListSDP": {
"type": "vb/ServiceDataProvider",
"defaultValue": {
"endpoint": "crmRestApi11_12_0_0/getall_resources",
"keyAttributes": "PartyNumber",
"itemsPath": "items",
"responseType": "page:getallResourcesResponse",
"transformsContext": {
"vb-textFilterAttributes": ["PartyName"]
},
"transforms": {
"request": {
"filter": "{{ $functions.processFilter }}"
}
}
}
}
It's important to note that the transformsContext object is an argument to every transforms function, so transforms authors can read the attributes and build the query that way.
define(['vb/BusinessObjectsTransforms'], function(BOTransforms) {
'use strict';
var PageModule = function PageModule() {};
/**
* The filter transform parses the text filter that may be part of the options and replaces
* it with an appropriate attribute filter criterion using the textFilterAttrs.
*
* Note: select-single provides a text filter in the form { text: 'someTextToSearch' }.
*
* The processing of the resulting filterCriterion is delegated to the Business Object REST API
* transforms module, which takes the filterCriterion and turns it into the 'q' param.
* @param textFilterAttrs
* @return a transforms func that is called later with the options
*/
PageModule.prototype.processFilter = function(config, options, transformsContext) {
const c = configuration;
let o = options;
let textValue;
let isCompound;
const tc = transformsContext;
const textFilterAttributes = tc && tc['vb-textFilterAttributes];
textValue = o && o.text;
// build your regular filtercriterion and delegate to VB BO REST API filter transforms
return BOTransforms.request.filter(configuration, o);
}
return PageModule;
});
Note:
Page authors are discouraged from configuring the SDP with the 'q' parameter directly, for example by setting a 'q' parameter in the uriParameters property. It is recommended that authors always use filterCriterion property to define 'q' criteria. This is especially important when using text filtering because the components always provide a filterCriterion which is appended to any configured filterCriterion on the SDP It becomes especially difficult for VB to reconcile the 'q' defined in uriParameters with the filterCriterion and authors are on their own to merge the two.
It's also important to note that select-single calls fetchByKeys very often to locate the record(s) pertaining to the select keys. For this reason, a new fetchByKeys transforms function has been added. Refer to the fetchByKeys transforms function for details.