Filters
Filters is also known as Criteria, used to filter an object or a set of objects through a chain of filtering functions. This document gives you a tour from creating some Filter
, creating FilterManager
, registering filters to FilterManager
and calling the filters.
Creating Filter
You can create a filter by either Declaring Filter class that implements an implicit Filter interface, or via FilterManager.create()
.
Declaring Filter Class
Every filter class must provide a function named apply
that returns a Promise
. Following example demonstrates a TaxFilter
that applies tax of 5% on a specified price and returns the price included tax in result:
class TaxFilter {
async apply(price) {
return price * 1.05;
}
}
or you can alternatively define TaxFilter
as a function if you don't want to use ES6 class syntax:
function TaxFilter() {
this.apply = function(price) {
return Promise.resolve(price * 1.05);
}
}
Creating Filter via Filter Manager
Another way (and also better) to create filter is to use FilterManager
. Instead of declaring a class, you simply call .create(fn)
on FilterManager
, in which fn
is the filtering function which can be either sync or async. Below is an example of creating a filter equivalent to the class TaxFilter
in previous section:
let taxFilter = filterManager.create(async (price) => price * 1.05));
or:
let taxFilter = filterManager.create(price => Promise.resolve(price * 1.05));
Creating Filter Manager
FilterManager
provides functionality for both filter registration and filter invocation. To create a new Filter Manager
:
const { filters } = require('robo-toolkit');
// or
const _f = require('robo-toolkit').filters;
const filterManager= _f.createManager();
Note that _f
is already a static instance of FilterManager
, so you can use it as a global FilterManager
.
Registering Filters
To register a Filter
to FilterManager
:
filterManager.add(name, filter, priority);
Parameter explanation:
name
is name of the filter. Multiple filters having same name will be chained. Once chained, each filter in sequence will use result from the previous filter as parameter to the filtering function.filter
is a Filter that is created using one of the methods mentioned in previous section.priority
is a number that indicates priority of the filter. The lower number, the higher priority. The filter that has higher priority will be invoked sooner.
Let's register the TaxFilter
with a priority of 1:
_f.add('calculate-price', new TaxFilter(), 1);
or alternatively:
_f.add('calculate-price', _f.create(async (price) => price * 1.05)), 1);
Add another filter that discounts the sale price by 10%. This filter should be called prior to tax calculation. We will register it with a higher priority than the TaxFilter
, 0 for example:
const discount = 0.1;
_f.add('calculate-price', _f.create(async (price) => price - (price * discount)), 0);
Now we have discount calculation placed on top of tax calculation. Whenever the filter calculate-price
is called, discount will be calculated first, then its result will be passed to the tax calculation.
Applying Filters
To apply a filter:
let result = await _f.apply(name, initialValue);
In which:
name
is name of the filter.initialValue
is an object or whatever that will be passed as the only parameter to filtering function of the very first filter in the sequence.result
is the final result returned from the last filter in sequence. If there is no registered filters, the initial value will be returned.
Let's invoke the filter calculate-price
with an initial price of 100 bucks:
var finalPrice = await _f.apply('calculate-price', 100);
console.log('Final price is: ' + finalPrice);
Output console looks like:
Final price is: 94.50
Last updated