AngularJS Filter Array with Array - javascript

I am trying to use a ng-repeat filter, however i can't seem to get it working.
html:
<li dnd-draggable="item" ng-repeat="item in items| filter: integrateFilter">
</li>
Filter:
$scope.integrateFilter = function (item) {
return !$scope.integratesInput ?
item : (item.type == $scope.itemTypes[0].type);
};
The structure of the data:
$scope.itemTypes is an array of types that i want to filter with:
products: Array[2]
0: Object
type: "food"
1: Object
type: "beverage"
The "items" in the list is an array of objects like:
0: Object
name: "steak"
type: "food"
So basically i want to filter items with an Array ($scope.itemTypes). The filter i'm using right now only returns one result (0) the beginning of the array. is there a way to use a filter like this? or will i need to loop through the $scope.itemTypes?
Thanks

Related

json object list sort using id column in angular js

I need to sort my json data object before render the browser. this is the my json format
$scope.cityData= [
{
id: '520',
city:'col01'
},
{
id: '410',
city:'col02'
},
{
id: '412',
city:'col03'
}]
I tried to do it. but something wrong in my code. I console log it. but did not sort
$scope.cityData.sort(function (a, b) { return a.id - b.id });
console.log($scope.cityData);
$scope.newCitySort = $scope.cityData;
I need to assign this sorted data to new scope variable also. how i do this ?
If you don't need the actual $scope.cityData to be sorted. You can just use the orderBy filter
In your html
<ul ng-repeat="city in cityData | orderBy: 'id' ">
<li>**your list rendering code here**</li>
</ul>
And this will render your collections ordering it by id

AngularJs Filter array objects with property file extension [duplicate]

If I have a complex object with objects as property values, how can I filter by one of the nested properties?
Can this be done with the OOB ng-repeat filter?
Data
{
Name: 'John Smith',
Manager: {
id: 123,
Name: 'Bill Lumburg'
}
}
ngRepeat
<li ng-repeat="e in emps | filter:Manager.Name">{{ e.Name }}</li>
You need to pass in the argument to filter by:
<input ng-model="filter.key">
<ul>
<li ng-repeat="e in list | filter: {Manager: {Name: filter.key}}">
{{e.Name}} (Manager: {{e.Manager.Name}})
</li>
</ul>
Example on Plunker
If you are filtering multiple properties then the syntax would be similar to below.
<ul>
<li ng-repeat="item in list | {filter: top_object_property_name: value, top_object_property_with_nested_objects_name: {nested_object_property_name: value}}">
...
</li>
</ul>
eg:
var employees = [name: 'John', roles: [{roleName: 'Manager'},{roleName: 'Supervisor'}]];
<li ng-repeat="staff in employees | {filter: name: 'John', roles: {roleName: 'Manager'}}">
...
</li>
To filter with multiple deep property we need to create custom filter.
What i mean we need to create our own function to filter the data in object and return the required object(filtered object).
For example i need to filter data from below object -
[
{
"document":{
"documentid":"1",
"documenttitle":"test 1",
"documentdescription":"abcdef"
}
},
{
"document":{
"documentid":"2",
"documenttitle":"dfjhkjhf",
"documentdescription":"dfhjshfjdhsj"
}
}
]
In HTML we use ng-repeat to show document list -
<div>
//search input textbox
<input ng-model="searchDocument" placeholder="Search">
</div>
<div ng-repeat="document in documentList | filter: filteredDocument">
//our html code
</div>
In Controller we write filter function to return filtered object by using two properties of object which are "documenttitle" and "documentdescription", code example is as below -
function filterDocuments(document)
{
if($scope.searchDocument)
{
if(document.documentTitle.toLowerCase().indexOf($scope.searchDocument.toLowerCase()) !== -1 || document.document.shortDescription.toLowerCase().indexOf($scope.searchDocument.toLowerCase()) !== -1)
{
//returns filtered object
return document
}
}else {
return document;
}
}
Where $scope.searchDocument is the scope variable which binded to the search textbox (HTML input tag) in which user can input the text to search.
In latest version of angularjs nested obj filter implemented by default.can use filter normally.
It for angular 1 only

AngularJS filter as selector from array

I'm having two array in my scope: employees and cars. Every employee has a carId which matches a car out of the cars-array.
Employee looks like
[{'id': 1, 'name': 'John', 'carId': 1}]
Car like
[{'id': 1, 'color': 'red'}]
Now I have an ng-repeat and would like to output the color of the car directly with an filter:
{{ employee.carId | selectFromCars:$scope.cars }}
I don't know how to get access to the cars array inside the filter. Is this even possible or should I inject the car into the employee after loading and then just use following?
{{ employee.car.color }}
you can make your own custom filter and just add it the end of your controller like so:
.filter('empCarFilter', function() {
return function(carId, cars) {
// you can access $scope.cars here, for example...
angular.forEach(cars,function(value){
if (value.id === carId) {
return value.color;
}
// etc...etc...
})
}
The above method is under the assumption that you are passing employee.carId into the filter. But, not sure how useful this would be for you, but you can pass the whole object to the filter as well and not just one key with:
{{ employee | empCarFilter }}
Here is also a pretty good reference for custom filters:
https://scotch.io/tutorials/building-custom-angularjs-filters

set v-show to true or false with a function

I have a list of properties (houses, flats,...) that I render with Vue.
Each property is shown or not according to some buttons that act like filters. Those "filters" are set in my data object:
data: {
properties: myPropertiesList,
rooms: {
1: false,
2: false,
3: false,
4: false,
},
type: {
flat: false,
house: false,
field: false
}
},
I set those option to true or false when user click on the options buttons.
Currently, I set v-show with the current expression:
v-show="rooms[property.Rooms] && type[property.Category]"
<div v-show="rooms[property.Rooms] && type[property.Category]"
class="col-md-3"
v-for="property in properties"
>
<property :property="property">
</div>
... And it works fine. However, I would rather like to do something like this:
v-show="showProperty(property)"
... and write that showProperty() function that return true or false.
Is something like that possible ?
If it is, where do you declare the function ? I tried in the methods object but it doesn't work.
The usage of a filter as proposed by Jeff is the way to go, but I want to answer your immediate question weither this is possible with a function, because it is.
You simply add the function to the components methods object:
methods: {
showProperty (property) {
return this.rooms[property.Rooms] && this.type[property.Category]
}
}
This looks like a call for v-for filtering:
...
data:function(){
properties:MyPropertyList,
rooms: [1,2,3,4],
types: ['flat','house','field']
},
...
<div v-for="property in properties | filterBy Room in rooms | filterBy Category in types"
class="col-md-3"
>
<property :property="property">
</div>
This will only show properties if property.Room is in the rooms array, and property.Category is in the types array.
If you need the rooms and types in objects like you have them now, you can use a computed property to create the array for filtering.
computed:{
roomList:function(){
//go through the rooms object and return an array of the true ones
}
}
If you want to filter with a custom function you can:
<div v-for="property in properties | filterBy showPropertyFilter rooms type">
And before all of this, create the filter:
Vue.filter('showPropertyFilter',function(properties, rooms, type){
//return only the properties that should show
});

Subsetting and editing array of objects in Javascript/Jquery

I have an array of object in Javascript that I want to subset based on key-value matches. In principle I want to access my array js_obj, change some objects where cond is true and then move on.
Let's say the array looks like this
js_obj = [{
word: "airport",
pic: "<img id='pic' src='../images/location/airport.png'/>",
cat: "location",
type: "undetermined"
}, {
word: "station",
pic: "<img id='pic' src='../images/location/station.png'/>",
cat: "location",
type: "undetermined"
}]
I now want to access js_obj where .word == "station" and of this selected object I want to change .type to "type_abc".
I was able to use each and select the object where the condition applies and change its .type as wanted, but I would like to do this within the original array. I do not simply want to filter out this object but find it, edit it, and leave the array in the modified state.
I found related posts referring to underscore.js but I think I didn't know which method to look for.
Can anybody help me with this indexing/subsetting problem?
Looping the array, checking the condition and modifying will keep it in the original array:
function modifyArrOfObjs(arr, key, condition, updateKey, updateValue) {
arr.forEach(function(obj) {
if (obj[key] == condition) {
obj[updateKey] = updateValue;
}
});
}
modifyArrOfObjs(js_obj, "word", "station", "type", "type_abc");

Categories