Reputation: 41
How to change object's attribute's values on a ng-repeat
loop using a filter function?
My project is a shopping cart that list products depending on the view and I have an argument 'discount' which will cut 50% off the price of the product and I wish to apply the change using a filter on the ng-repeat
.
My data structure is :
[{
"categorie": "",
"name": "",
"price": 12
}]
My ng-repeat
loop looks like:
ng-repeat product in products |filter:'priceFilter()
and my function defined inside the controller is:
var priceFilter = function(product){
var filtered = [];
if (discount == true) {
for (var i = 0; i< product.length; i++) {
product.price = prix.price /2;
filtered.push(product);
}
}
return filtered;
}
What am I missing? Right now it filters out all the results, sending back nothing.
Upvotes: 2
Views: 5590
Reputation: 1270
Try:
Html:
<div ng-repeat="product in products">
<div>
{{applyDiscount(product.Price}}
</div>
</div>
js
$scope.applyDiscount= function(price){
if ($scope.discount)
{
return price /2;
}
return price;}
As Camusensei said, the applyDiscount
function will be run on every digest cycle, slowing the application down.
For performance issues, a better implementation would use a filter which is only run if the input changes.
Html:
<div ng-repeat="product in products">
<div>
{{product.price | priceFilter:discount}}
</div>
</div>
Js:
myApp.filter("applyDiscount", function() {
return function(price, discount) {
if (discount)
{
return price /2;
}
return price;
};
});
Upvotes: 1
Reputation: 851
filter is not what you want for this scenario, a custom filter should be used to determine whether something is valid or invalid. and should only return a true or false. All a filter is going to do is look at the current object in the list and determine whether it meets certain criteria to show in the list or not.
you should just change your html.
<div ng-repeat="product in products">
<div ng-if="discount">
{{product.Price / 2}}
</div>
<div ng-if="!discount">
{{product.Price}}
</div>
</div>
edit:
if you want to change your data then your don't want to use a filter. you need to figure out before you loop what the data should show. if your discount is a simple checkbox you can add an ng-change="adjustprice()"
to the checkbox and have adjustprice() do the manipulation. you don't want to touch ng-repeat data inside the ng-repeat. angular doesn't like this and will break stuff if you attempt it.
Upvotes: 0
Reputation: 1563
This is not the right way of using a custom filter As shown in that example, you need to add this line to your code:
angular.module("yourmodulename").filter('priceFilter', function() { return priceFilter; });
And you also need to change your html to:
<ng-repeat="product in products | priceFilter">
Upvotes: 2