My project has been written on AngularJS and now it is migrating to the modern Angular 8.
One of then migration steps is rewrtiting code from Javascript to Typescript. And I have faced a tricky issue with the ng-repeat' filter feature.
What I had. The HTML template:
<div ng-repeat="menuItem in items| filter: vm.filterMenuItem">
It’s a little strange that when calling a function, you don’t need to specify a passed argument.
And the JS code:
function filterMenuItem(menuItem) {
let paramFits = vm.filters.param === 0 || menuItem.param === vm.filters.param;
let anotherParamFits = vm.filters.anotherParam === 0 || menuItem.anotherParam === vm.filters.anotherParam;
return paramFits && anotherParamFits;
}
Where vm.filters
is a controller level variable which can be changed from the template.
Then I rewrited it to the TS:
filterMenuItem(menuItem: MenuItemClass) {
let paramFits = this.filters.param === 0 || menuItem.param === this.filters.param;
let anotherParamFits = this.filters.anotherParam === 0 || menuItem.anotherParam === this.filters.anotherParam;
return paramFits && anotherParamFits;
}
... and it all broke. For some reasons AngularJS not recorgnizes proper controller-lever this
inside the function. In this case this
is undefined.
Is there any way to keep a custom filter function with the Typescript?
Custom filter function should be modified:
filterMenuItem(menuItem: MenuItemClass, filters) {
return menuItem => {
let paramFits = filters.param === 0 || menuItem.param === filters.param;
let anotherParamFits = filters.anotherParam === 0 || menuItem.anotherParam === filters.anotherParam;
return paramFits && anotherParamFits;
}
}
And the HTML template should be modified like this:
<div ng-repeat="menuItem in items | filter: vm.filterMenuItem(menuItem, vm.filters)">
The key changes:
menuItem
) we want to check with the filter and the filter criteria (vm.filters
), and pass it explicitly to the function. And there is no this
calls.