Custom Filter not firing in angular1 - angularjs

I have two fields in a digest: genres and secondary_genre which are integers.
I have a dropdown fields of genres which returns a value (ng-model = query.genres)
I have tried to create a custom function which will compare genre and secondary genre to query.genre and return if EITHER condition is met. Individually they work fine i.e with filter:{secondary_genre:query.genre) but for the OR condition I need a custom.
The custom filter I have written is called with
<li ng-repeat="film in listOfTitles | customGenreFilter:query.genre">
The filter is
.filter('customGenreFilter', function() {
return function(data, query) {
if (data) {
return data.filter(data.genres == query || data.secondary_genre == query);
}
else {
return [];
}
};
});
but it is throwing errors. How can I write this custom filter to return the item if the condition genres = query.genre OR secondary_genre = query.genre.

Your filter is not working because you are not using the .filter() method properly, the method require the argument to be a lambda function in which return whether the item should or not stay in the list. In order to fix your code you have to change the following line:
return data.filter(data.genres == query || data.secondary_genre == query);
To:
return data.filter(function(item) {
return item.genre == query || item.secondary_genre == query
});
The following example implements a working version of your filter.
angular.module('myApp', [])
.component('app', {
templateUrl: '/app.html',
controller: App
})
.filter('customGenreFilter', CustomGenreFilter);
function App($scope) {
$scope.query = {
genre: ''
};
$scope.listOfTitles = [
{ title: 'test 1', genre: 'genre1' },
{ title: 'test 2', genre: 'genre2' },
];
}
function CustomGenreFilter() {
return function(data, query) {
if (query === '') return data;
if (data) return data.filter(function(item) {
return item.genre == query || item.secondary_genre == query
});
return [];
};
}
angular.element(function() {
angular.bootstrap(document, ['myApp']);
});
<script id="/app.html" type="text/ng-template">
<select ng-model="query.genre" ng-options="item as item for item in ['', 'genre1', 'genre2']">
</select>
<ul>
<li ng-repeat="film in listOfTitles | customGenreFilter:query.genre">
{{ film.title }}
</li>
</ul>
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<app />

Related

Add an item to a firebase collection

I need to append an item in one or more collections in Firebase Database using angularfire (AngularJS)
For example, if I have:
users {
Marcelo: {
userid: 1
},
Javier: {
userid: 2
}
}
How can I append a new item in each collection, getting something like this?
users {
Marcelo: {
userid: 1
state: "enabled"
},
Javier: {
userid: 2
state: "enabled"
}
}
There is no specific AngularFire operation for this. But since AngularFire is just built on top of the Firebase JavaScript SDK, you use that to read the data and loop over it and then update each item.
A short snippet to get you started:
var ref = firebase.database().ref("users");
users.once("value", function(snapshot) {
snapshot.forEach(function(userSnapshot) {
userSnapshot.ref.update({ state: "enabled" });
});
});
In this sample we create a function to insert param in our object
//object = users object
//key = state or something else
//value = true or something else
var insertParam = function(object, key, value) {
for (var _key in object) {
object[_key][key] = value;
}
}
var app = angular.module("app", []);
app.controller("ctrl", [
"$scope",
function($scope) {
$scope.users = {
Marcelo: {
userid: 1
},
Javier: {
userid: 2
}
}
var insertParam = function(object, key, value) {
for (var _key in object) {
object[_key][key] = value;
}
}
insertParam($scope.users, "state", true);
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="(key, option) in users">
{{key}}
<ul>
<li><b>userId:</b> {{option.userid}}</li>
<li><b>state:</b> {{option.state}}</li>
</ul>
</li>
</ul>
</div>

filter multiple values in single column in angularjs

How could i return couple name:[apple, orange, carrot]
[http://jsfiddle.net/GruffBunny/QHtD8/2/]1
function MyCtrl($scope) {
$scope.products = [
{id:"1",type:"fruit"},
{id:"2",type:"meat"},
{id:"3",type:"drink"},
{id:"4",type:"vegetable"},
{id:"5",type:"dairy"}
];
$scope.fruitOrVeg = function(product){
return product.name == ['1','4','5'];
};
Thank you very much
Change your template, to call function:
<li ng-repeat="item in products | filter:fruitOrVeg()">{{item.name}}</li>
and filter function, return new function
$scope.fruitOrVeg = function() {
return function(item) {
return ['1', '4', '5'].indexOf(item.id) > -1;
}
};
Added JSFiddler
Try using an AngularJS custom filter.
app.filter('filterByFruitOrVeg', function() {
return function(array) {
arr = arr.filter(payment, function(objectInArray) {
return objectInArray.type === 'fruit' || objectInArray.type === 'vegetable';
});
}
});

Calling $scope in custom filter (angular)

I'm using this angular filter to filter out objects in an array whose localteam_id properties match a value that is held in $scope.whichMyteam. This works fine.
VIEW
<div ng-repeat="fixture in getFixtures | filter: {localteam_id: whichMyteam} ">
I want to extend the filter however, to include a section criterion: so it will, in effect, be:
<div ng-repeat="fixture in getFixtures | filter: {localteam_id: whichMyteam && visitorteam_id: whichMyteam} ">
...but a) this doesn't work, and b) even if it did, it's getting a little cumbersome and seems that it would justify making a custom filter.
So, I tried to make one. The problem I ran into is I need to reference the $scope.whichMyteam value in the filter, but it seems the filter module can't accept/understand $scope. This is crucial for the filter to work in my instance, so I'm not sure how to resolve this.
My filter so far looks like this:
app.filter('myFixtures', function() {
return function(input) {
angular.forEach(input, function(o) {
output = [];
if (o.localteam_id === $scope.whichMyteam) {
output.push(o);
}
return output;
})
};
});
The above is a simplified version which only attempts to match one property (just did this to test it and reduce the number of moving parts). When I call it in the view though...
<div ng-repeat="fixture in getFixtures | myFixtures">
...it doesn't work. Console logs '$scope is not defined'.
UPDATE: I tried this, still not working!
FILTER
var myFilters = angular.module('myFilters', [])
myFilters.filter('myFixtures', function(whichMyteam) {
return function(input) {
angular.forEach(input, function(o) {
output = [];
if (o.localteam_id === whichMyteam) {
output.push(o);
}
return output;
})
}
});
VIEW
<div ng-repeat="fixture in getFixtures | myFixtures(whichMyteam)">
Console is logging a syntax error (I think...)
angular.js:13236 Error: [$parse:syntax]
How about having your filter function return a function.
app.filter('myFixtures', function() {
return function(input, whichMyteam) {
output = [];
angular.forEach(input, function(o) {
if (o.localteam_id === whichMyteam) {
output.push(o);
}
})
return output;
};
});
Then call the filter function passing in your variable
<div ng-repeat='fixture in getFixtures | myFixtures:whichMyteam'>
--- example
angular
.module('app', [])
.filter('otherFilter', otherFilter)
.controller('controller', controller);
controller.$inject = ['$scope'];
function controller($scope) {
$scope.things = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
$scope.modVal = 2;
console.log('controller');
$scope.myFilter = function(x) {
return function(y) {
return (y % x) === 0;
}
};
}
function otherFilter() {
return function(y, x) {
var out = [];
angular.forEach(y, function(val) {
if ((val % x) === 0) {
out.push(val)
}
});
return out;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='controller'>
<div ng-repeat='thing in things | filter:myFilter(modVal)'>
{{ thing }}
</div>
<br/>
<div ng-repeat='thing in things | otherFilter:modVal'>
{{ thing }}
</div>
</div>
You have 2 problems here:
1. How to pass a param, html:
<div ng-repeat="fixture in getFixtures | myFixtures:whichMyteam">
js:
myFilters.filter('myFixtures', function() {
return function(input, whichMyteam) {
...
Do not place return statement inside forEach -- it does not make what you think;)
So finally your filter is:
myFilters.filter('myFixtures', function() {
return function(input, whichMyteam) {
output = [];
angular.forEach(input, function(o) {
if (o.localteam_id === whichMyteam) {
output.push(o);
}
})
return output;
}
});
http://plnkr.co/edit/0XFfI8hIdCaJ19gJRYr2?p=preview

ng-if check on an filter input in Angular

I have a simple filter that puts one of two statements, based on if a input from SQL is true
app.filter('yesNo', function() {
return function(input) {
return (input == '1') ? 'Skal tjekkes!' : 'Alt OK';
}
});
And then should change a menu item based on that;
<li role="presentation"><a href="#" data-ng-click="statusFilter = 'Ny ordre'">New Orders
<div ng-if="input == '1' | outdated">
<p>Needs to be checked: {{(orders | filter:{status:'ny ordre', outdated: '1'}).length}}</p>
</div>
<div ng-if="!input == '1' | outdated">Shows regardless</div>
</a></li>
I am missing something, just no idea what. :(
You have an example here for how to use a custom filter function: http://jsfiddle.net/alexdumitrescu/zv6cf7nq/
var myApp = angular.module('myApp', [])
.filter('myfilter', function() {
return function(orders) {
return orders.filter(function(order) {
return order.outdated == '1';
})
}
});
function MyCtrl($scope) {
$scope.orders = [{
status: 'my order1',
outdated: '1'
}, {
status: 'my order2',
outdated: '0'
}];
}
<div ng-controller="MyCtrl">
{{orders | myfilter}}
</div>

Removing Items From Favourite List

I am working on angular js on single page application in mvc arcitecture i have a list of favourites i want to delete on my click event
Html For Angular
<div class="favourite" ng-repeat="favourite in category.favourites | orderBy:'title'">
<a class="title" ng-href="{{favourite.url}}" ng-bind-html="favourite.title | mlStripHtml"></a>
<div ng-if="profileFavourites.canDelete" class="remove" title="{{ 'TaBort' | mlLocalization }}" ng-click="profileFavourites.remove(favourite, $event,$index)"></div>
</div>
Angular Js
FavouriteService.getFavourites(profileId).then(
function (favourites) {
$scope.categories = []
_.forEach(favourites, function (fav) {
var category = _.find($scope.categories, function (cat) {
$scope
return cat.id == fav.type
})
if (category) {
category.favourites.push(fav)
return
}
category = {
id: fav.type,
name: Language.getTypeName(fav.type, {
case: 'none'
}),
favourites: [fav]
}
$scope.categories.push(category)
})
$scope.isLoadingFavourites = false
})
$scope.remove = function (favourite, $event) {
$event.preventDefault()
$event.stopPropagation()
FavouriteService.removeFromFavourites(favourite.id).then(
function () {
alert("favourite")
var category = _.find($scope.categories, function (cat) {
return cat.id == favourite.type
})
if (category) return
_.remove(category.favourites, function (fav) {
return fav.id == favourite.id
})
if (!category.favourites.length) {
_.remove(scope.categories, function (cat) {
return cat.id == category.id
})
}
})
}
The above mention is my code for the removal of item from the list it works perfectly fine when i click on delete link it successfully delete the item but the onlu issue is it does not reflect the change till the page gets refrehed i m tryingh hard but could not resolve it as i m new to angular js any help will be appreciated
you are passing $index in remove method so you can use below code to remove favourite
$scope.remove = function (favourite, $event,index) {
$event.preventDefault()
$event.stopPropagation()
FavouriteService.removeFromFavourites(favourite.id).then(
function () {
alert("favourite")
$scope.category.favourites.splice(index,1);
})
it will refresh your list.

Resources