Reputation: 805
I'm using $filter to iterate through an array and fetch a specific value
Below is my code:
var selected = $filter('filter')($scope.folders, {url: el.selected[0] });
This code is working, but I got a problem when the url contain an accent and space like so :
/Users/Me/project/products/Poste à souder
In that case the string comparaison isn't working anymore.
What is the cleaner way to solve this situation ?
Upvotes: 1
Views: 172
Reputation: 1838
Maybe it's best to write your own filter:
app.filter("customFilter", function () {
//the filter will accept an input array, the key you want to look for and the value that the key should have
return function (array, key, value) {
return array.filter(function(x){
return (x.hasOwnProperty(key) && (x[key] === value));
});
};
});
And use it in your controller like:
$scope.filtered = $filter("customFilter")($scope.folders, "url", "/Users/Me/project/products/Poste à souder");
Check out a working demo here.
Upvotes: 0
Reputation: 1909
That true. As a francophone, I've often encounter encoding/decoding issues with angularjs.
The source code of the default filter is as follow
function filterFilter()
{
return function(array, expression, comparator)
{
if (!isArrayLike(array))
{
if (array == null)
{
return array;
}
else
{
throw minErr('filter')('notarray', 'Expected array but received: {0}', array);
}
}
var expressionType = getTypeForFilter(expression);
var predicateFn;
var matchAgainstAnyProp;
switch (expressionType)
{
case 'function':
predicateFn = expression;
break;
case 'boolean':
case 'null':
case 'number':
case 'string':
matchAgainstAnyProp = true;
//jshint -W086
case 'object':
//jshint +W086
predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp);
break;
default:
return array;
}
return Array.prototype.filter.call(array, predicateFn);
};
}
and the predicate
generator stand as follow: it generate the default comparator if the provided one is not a function
function createPredicateFn(expression, comparator, matchAgainstAnyProp)
{
var shouldMatchPrimitives = isObject(expression) && ('$' in expression);
var predicateFn;
if (comparator === true)
{
comparator = equals;
}
else if (!isFunction(comparator))
{
comparator = function(actual, expected)
{
if (isUndefined(actual))
{
// No substring matching against `undefined`
return false;
}
if ((actual === null) || (expected === null))
{
// No substring matching against `null`; only match against `null`
return actual === expected;
}
if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual)))
{
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
actual = lowercase('' + actual);
expected = lowercase('' + expected);
return actual.indexOf(expected) !== -1;
};
}
predicateFn = function(item)
{
if (shouldMatchPrimitives && !isObject(item))
{
return deepCompare(item, expression.$, comparator, false);
}
return deepCompare(item, expression, comparator, matchAgainstAnyProp);
};
return predicateFn;
}
Too much speech. You have the choice:
comparator
to your filter see the doc
You can write your own filter
.filter('myCustomFilter', function()
{
return function(input, criteria)
{
... // your logic here
return ...// the filtered values
};
})
Upvotes: 1