Plunk with examples.
In Angular 1.4 a change has been introduced for $filter('filter') to throw an error when it doesn't operate on an array.
The problem with this is that UI Bootstrap's typeahead used this to query and filter async results.
// controller
$scope.getActors = function(val) {
var deferred = $q.defer();
var promise = deferred.promise;
var values = [
{label: 'Jeff Goldblum', value: 1},
{label: 'Casey Affleck', value: 2},
{label: 'Tom Cruise', value: 3}
];
// fake an async call
$timeout(function() {
deferred.resolve(values);
}, 1500)
return promise;
}
// directive
typeahead="actor as actor.label for actor in getActors($viewValue) | filter:{label:$viewValue}"
However, this now throws an error because what is returned before any results is a $promise object, causing $filter('filter') to fail.
I thought maybe I could wrap filter in another filter to return an empty array before the promise was resolved, but no such luck.
// filter
.filter('asyncFilter', function($filter) {
return function(val) {
return angular.isArray(val) ? $filter('filter')(val) : [];
};
})
// directive
typeahead="actor as actor.label for actor in getActors($viewValue) | asyncFilter:{label:$viewValue}"
You can use $filter directly in your getActors() function, like so. Also just FYI, $timeout returns a promise, so you don't need to use deferreds in the fake example :)
$scope.getActors = function(val) {
var values = [
{label: 'Jeff Goldblum', value: 1},
{label: 'Casey Affleck', value: 2},
{label: 'Tom Cruise', value: 3}
];
// fake an async call
return $timeout(function() {
return values;
}, 1500).then(function(results) {
return $filter('filter')(results, {
label: val
});
});
}
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