I was reading the AngularJS developer guide on the Filter section (https://docs.angularjs.org/guide/filter#stateful-filters) and came across "Stateful Filters".
This description is given as follows:
It is strongly discouraged to write filters that are stateful, because the execution of those can't be optimized by Angular, which often leads to performance issues. Many stateful filters can be converted into stateless filters just by exposing the hidden state as a model and turning it into an argument for the filter.
I'm new to web development, so have no idea what Stateful filtering is, and Angular Documentation didn't explain it either :( Can someone please explain what is the difference between a normal filter and a stateful filter is?
The “filter” Filter in AngularJS is used to filter the array and object elements and return the filtered items. In other words, this filter selects a subset (a smaller array containing elements that meet the filter criteria) of an array from the original array.
Introduction to AngularJS Custom Filter. In AngularJS filters are used to modify or update the data before rendering the data on view or UI. Filters are clubbed in expression or directives using pipe (|) symbol.
Filters are used to modify the data. They can be clubbed in expression or directives using pipe (|) character.
"State" is referring to variables/properties/etc that are set throughout the application. These values have the potential to change at any given time. The docs are saying that the filter shouldn't depend on external "state". Anything the filter needs to know about should be passed in as an argument when filtering, and the filter should then have everything it needs to do the filtering and return the result Look over the demo in the docs and you'll see that in the "stateful" filter, the filter has a dependency on a service which it uses to do the filtering. That service value could change during a $digest
cycle, so the $stateful
property has to be set on the filter so that Angular will run the filter again to be sure that dependency hasn't changed state, this changing the filter's result.
So, all "state" should be in the arguments, like this:
<p>{{myData | multiplyBy:multiplier}}</p>
With a filter like:
.filter('multiplyBy', function() { function filter(input, multiplier) { return input * multiplier; } return filter; })
If the data or arguments change, the filter will run again.
The stateful
version would be something like this (not recommended!):
<p>{{myData | myFilter}}</p>
And the filter gets it's needed information from external sources:
.filter('myFilter', ['someDependency', function(someDependency) { function filter(input) { // let's just say `someDependency = {multiplier: 3}` return input * someDependency.multiplier; } filter.$stateful = true; return filter; }])
In that sample filter, someDependency.multiplier
should have been passed in as an argument to the filter (as in the first example), rather than being a dependency of the filter.
To further clarify the problem: If you called a function like this: foo(20)
and get a result of 40
, you should get the same result if you repeat the process. If you called foo(20)
again and got 92
, that would be rather confusing, right? Assuming foo
isn't a function that is made to return random values, the only way it could return different numbers each time is if it performs differently based on a hidden state (something changing internally, rather than being passed in as an argument). The idea that the function would return the same each time given the same arguments is called being "idempotent".
Note: $stateful
seems to be new in Angular 1.3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With