AngulaJS filter on array of object - angularjs

I have this JSON object.
var UsersList=[
{
"User" : {
"IdUser" : "admin",
"FirstName" : "mirco",
"LastName" : "sabatino"
}
}, {
"User" : {
"IdUser" : "coordinator",
"FirstName" : "coordinator",
"LastName" : ""
}
}, {
"User" : {
"IdUser" : "test",
"FirstName" : "publisher",
"LastName" : "Diaz"
}
}, {
"User" : {
"IdUser" : "work",
"FirstName" : "ingester",
"LastName" : "Brown"
}
}
] ;
I want filter in ng-repeat for LastName value.
<div class="col-md-6" ng-repeat="users in UsersList | filter: {User.LastName : filterSearchLetter}">
filterSearchLetter value in my controler is populated by
$scope.filterLetterUser=function(letter){
$scope.filterSearchLetter=letter;
console.log($scope.filterSearchLetter);
};
But this don't work.

See my plnkr for the solution http://plnkr.co/edit/l27xUQ?p=preview. I also have implemented your required UI behavior using ng-change. Hope it helps.
For detailed explanation I offer you Todd Motto's blog - http://toddmotto.com/everything-about-custom-filters-in-angular-js/
To invoke a filter, the syntax is the filter function name followed by the parameters.
To define a filter you need to do (This is copy of Todd Motto's code modified for your data)
todos.filter('startsWithLetter', function () {
return function (items, letter) {
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.User.LastName.substring(0, 1))) {
filtered.push(item);
}
}
return filtered;
};
});

This is not a valid object: {User.LastName : filterSearchLetter} It should actually throw an exception saying something like
Uncaught SyntaxError: Unexpected token .
What you probably want to try instead is: {"User": {"LastName" : filterSearchLetter} }

To iterate over an array of Objects see:
angularjs - ng-repeat: access key and value from JSON array object
You may have to convert to valid JS object using JS_Obj=JSON.parse(JSON_Obj);
Maybe something like this:
//iterate through array
<ul ng-repeat="users in UsersList">
//iterate through Object
<li ng-repeat=(key, value) in users | filter: {User.LastName : filterSearchLetter}>
{{key}} : {{value}}
</li>
</ul>

Related

json arrays of object with quotaions mark

I am trying to send an json object to my apiController :
myJson Object that I construct dynamicaly like this :
var course= new Object();
course.info= $scope.info;
course.studentList = [];
course.studentList = $scope.results;
$scope.results is an array that I get from my view :
<select ng-model="results[$index]" >
<option value=""></option>
<option ng-repeat="r in myList" value={{r}}>{{r.studlastname}}</option>
</select>
what I expect :
{
"course": {
"courseName":"yyy",
"courseDesc":"xxxx",
"prof":"prof1"
},
"studentList" :[
{"studfirstname":"2","studlastname":"","studAge":"21"},
{"studfirstname":"4","studlastname":"","studAge":"40"},
{"studfirstname":"6","studlastname":"","studAge":"60"}
]
}
what I have :
{
"course": {
"courseName":"yyy",
"courseDesc":"xxxx",
"prof":"prof1"
},
"studentList" :[
"{"studfirstname":"2","studlastname":"","studAge":"21"}",
"{"studfirstname":"4","studlastname":"","studAge":"40"}",
"{"studfirstname":"6","studlastname":"","studAge":"60"}"
]
}
notice the quotations on every studentList element, this is causing deserialization problem on server side.
please can you help me to remove the quotations ?
thank you in advance.
From what I can see, Problem here is this
course.studentList = $scope.results;
because this line is adding string into your JSON Object as ng-model gives you string instead of object what you are adding in JSON Array.
course.studentList = JSON.parse($scope.results);
I found an easy solution :
let objectArray = $scope.results.map((each)=>{return JSON.parse(each)});
course.studentsList = objectArray;
this solved my problem.

ng-repeat in angularJs avoid duplicate values

I have object like this
{
{
"assetId" : "560",
"assetName" : "Testname",
"message" : "hai",
"timestamp" : 1452585984181
},
{
"message" : "haii",
"timestamp" : 1452585999592
},
{
"assetId" : "560",
"assetName" : "Testname",
"message" : "heloo",
"timestamp" : 1452586221604
}
}
show to this object i am using ng-repeat. My question is
I need to show all message using ng-repat comes under single assetName. but in this object two objects have same assetName and assetId. i need to show the messages both same objects but no need to repeatably show the assetName in top.
How can i only avoid the duplicate assetName and assetId. I used
<div class="container" data-ng-repeat="data in dataList | unique:'assetId'">
But it's completely removing the object. I need the message from all objects.
is it possible.Please help
This is the out put i am expecting.:
I think you should create your own custom filter
yourApp.filter('customuniqueFilter', function() {
return function( array, propertyThatMustBeUnique) {
var newArray = [];
for (i = 0; i++; i < array.length){
if ( notYetInYourArray ){ // I was too lazy to think about a way to do it ;-) feel free to update my answer
newArray.push(array[i]);
}
}
return newArray;
}
});
and then use it like this :
<div class="container" data-ng-repeat="data in dataList | customunique:'assetId'">
How about this:
<div class="container" data-ng-repeat="data in dataList | unique:'assetId'">
<span>{{data.assetId}}</span>
<div data-ng-repeat="data2 in dataList | filter:(data.assetId === undefined ? {assetId:'!'} : data.assetId)">
<span>{{data2.message}}</span>
</div>
</div>

how to check the result returned by filter in null or not and if it is null need to call a function in the controller

The result of list returned by the filter test_id needs to be checked.If the list is null need to call a function in the controller.
<div class="test_list">
<ul>
<p> testID :{{test_id}}</p>-->
<li ng-repeat="test in test_list | filter: test_id">
{{test}}
</li>
</ul>
</div>
Thanks in advance.
Add a watch over the list variable in your controller and filter it programatically and call the necessary function if found null.
$scope.$watch("test_id", function(new_test_id) {
//inject $filter service in your main controller
var filtered_test_val=$filter('filter')($scope.test_val, new_test_id, false);
if(angular.isUndefined(filtered_test_val) || filtered_test_val== null)
{
//call your function here.
}
}
You just need a custome filterfor this :-)
<div ng-app="myapp">
<div ng-controller="test">
<input type="text" ng-model="search">
<div ng-repeat="data in myData | filterData:search">
{{ data.ID }}
{{ data.Message }}
</div>
</div>
</div>
angular.module('myapp',[])
.controller('test',function($scope){
$scope.myData = [
{
"ID" : "001",
"Message" : "test test test test"
},
{
"ID" : "002",
"Message" : "test test test test"
},
{
"ID" : "003",
"Message" : "test test test test"
},
{
"ID" : "004",
"Message" : "test test test test"
},
{
"ID" : "005",
"Message" : " "
},
{
"ID" : "006",
"Message" : "test test test test"
},
{
"ID" : "007",
"Message" : "test test test test"
},
{
"ID" : "007",
"Message" : null
}
];
})
.filter('filterData',function(){
return function(data,search) {
if(!search || search.length<3){
return data;
}
var dataToBePushed = [];
for(var i=0;i<data.length;i++){
if(data[i].ID==search){
dataToBePushed.push(data[i]);
}
}
if(dataToBePushed.length==0){
alert("My function");
}else{
return dataToBePushed;
}
}
});
PS:- I checked the search after length is 3 but it may help you to clear the idea and you can manupilate it according to your requirement.
Fiddle
You can make use of the built-in filter filter in your own custom defined filter.
.filter('checknull', function($filter) {
return function(x, test) {
var result = $filter("filter")(x, test);
if (result.length <= 0)
myFunc();
return result;
}
});
Fiddle Here

how can I add groups under an active/inactive child?

I have successfully been able to send data to the firebase server however I am having trouble getting the data to send to the appropriate data subset I have created. When I send data made in the html form, It sends organized by ID number. I need it to be sent as a child to the 'groups' category in firebase.
here is a Plnkr with the server and $add working. Any suggestions I would really appreciate!
http://plnkr.co/edit/LZ24sRoSJjuCHQnEGzQz?p=linter
.controller('MainCtrl', ['$scope', 'groupsService', function( $scope, groupsService, $firebase ) {
$scope.newGroup = {
name: '',
status: ''
};
$scope.addGroup = function(newGroup) {
groupsService.addGroup(newGroup);
$scope.newGroup = {
name: '',
status: ''
};
};
$scope.updateGroup = function (id) {
groupsService.updateGroup(id);
};
$scope.removeGroup = function(id) {
groupsService.removeGroup(id);
};
}])
.factory('groupsService', ['$firebase', 'FIREBASE_URI',
function ($firebase, FIREBASE_URI) {
var ref = new Firebase(FIREBASE_URI);
var groups = $firebase(ref).$asArray();
var getGroups = function(){
return groups;
};
var addGroup = function (newGroup) {
console.log(newGroup)
groups.$add(newGroup);
};
var updateGroup = function (id){
groups.$save(id);
};
var removeGroup = function (id) {
groups.$remove(id);
};
return {
getGroups: getGroups,
addGroup: addGroup,
updateGroup: updateGroup,
removeGroup: removeGroup,
}
}]);
Thanks for responding! What I am trying to do is add dummy data (name and status) to the groups category like this:
{
Groups:[
"-JcFXid1A2G8EM7A_kwc" : {
"name" : "hi",
"status": "inactive"
},
"-JcFZP5FNtL4Yj6nja_7" : {
"name" : "hi"
"status": "inactive"
},
"-JcFtGoZL7J-CCIjTYcL" : {
"name" : "dfgdfg",
"status": "inactive"
}
]
}
would it make more sense to have them organized by active or inactive? I am afraid to nest too far in firebase...
like
{
Groups:[
"Active":[
"-JcFXid1A2G8EM7A_kwc" : {
"name" : "hi",
}
],
"Inactive":[
"-JcFZP5FNtL4Yj6nja_7" : {
"name" : "hi"
},
"-JcFtGoZL7J-CCIjTYcL" : {
"name" : "dfgdfg"
}
]
]
}
This isn't an answer to your question yet, because I first need to understand what you're trying to accomplish (and I can't fit this amount of information in a comment).
In your view you have a form that binds to the group's name and status:
<form role="form" ng-controller="MainCtrl" ng-submit="addGroup(newGroup)">
<div class="form-group">
<label for="groupName">Group Name</label>
<input type="text" class="form-control" id="groupName" ng-model="newGroup.name">
</div>
<div class="form-group">
<label for="groupStatus">Group Status</label>
<select class="form-control" ng-model="newGroup.status">
<option value="inactive">Inactive</option>
<option value="active">Active</option>
</select>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
In your GroupsService you essentially add a group like this:
var ref = new Firebase(FIREBASE_URI);
var groups = $firebase(ref).$asArray();
groups.$add(newGroup);
Which adds the group to the collection at that URL.
Which leads to this data structure:
{
"-JcFXid1A2G8EM7A_kwc" : {
"name" : "hi",
"status" : "inactive"
},
"-JcFZP5FNtL4Yj6nja_7" : {
"name" : "hi",
"status" : "active"
},
"-JcFtGoZL7J-CCIjTYcL" : {
"name" : "dfgdfg",
"status" : "active"
}
}
But if I understand you correctly you to want the data to be stored like this:
{
"inactive": [
"-JcFXid1A2G8EM7A_kwc" : {
"name" : "hi"
}
],
"active": [
"-JcFZP5FNtL4Yj6nja_7" : {
"name" : "hi"
},
"-JcFtGoZL7J-CCIjTYcL" : {
"name" : "dfgdfg",
}
]
}
Is this indeed what you're looking to do?
Are you ever going to display active and inactive groups combined in a list? This is important to know, since it is quite easy to filter a list in Angular, but I wouldn't know how to merge two lists.

AngularJS - Filter empty objects

I have a $scope.myData object that contain a chunk of data. What i am trying to do is display the data but filter out the nulls and empty strings:
$scope.myData = [
{
"ID" : "001",
"Message" : "test test test test"
},
{
"ID" : "002",
"Message" : "test test test test"
},
{
"ID" : "003",
"Message" : "test test test test"
},
{
"ID" : "004",
"Message" : "test test test test"
},
{
"ID" : "005",
"Message" : " "
},
{
"ID" : "006",
"Message" : "test test test test"
},
{
"ID" : "007",
"Message" : "test test test test"
},
{
"ID" : "007",
"Message" : null
}
]
I can perform an ng-repeat on the above and filter null's via:
<div ng-repeat="data in myData | filter:{Message: '!!'}">
{{ data.ID }}
{{ data.Message }}
</div>
But how can i filter the empty strings e.g:
"Message" : " "
Thanks
We can simply use ng-if here:
<div ng-repeat="data in myData " ng-if="data.Message">
{{ data.ID }}
{{ data.Message }}
</div>
You can use a function instead of an object like this
<div ng-repeat="data in myData | filter:emptyOrNull">
{{ data.ID }}
{{ data.Message }}
</div>
And in the controller
$scope.emptyOrNull = function(item){
return !(item.Message === null || item.Message.trim().length === 0)
}
Well you can create a custom filter:
.filter('hasSomeValue', [function(){
return function(input, param) {
var ret = [];
if(!angular.isDefined(param)) param = true;
angular.forEach(input, function(v){
if(angular.isDefined(v.Message) && v.Message) {
v.Message = v.Message.replace(/^\s*/g, '');
ret.push(v);
}
});
return ret;
};
}])
And in your HTML:
<div ng-repeat="data in myData | hasSomeValue: data.Message">
DEMO
You can use '' charter.
Try check like this.
<div ng-repeat="data in myData | filter:{Message: ''}">
You can use an angular filter for this:
Working Fiddle
Code Snippet:
.filter('filterData',function(){
return function(data) {
var dataToBePushed = [];
data.forEach(function(resultData){
if(resultData.Message && resultData.Message != " ")
dataToBePushed.push(resultData);
});
return dataToBePushed;
}
});
If you wanted to filter out values in an object that are empty, you could create a custom filter and filter each based on the value.
Something like this:
.filter("notEmpty",
function () {
return function (object) {
var filteredObj = {};
angular.forEach(object, function (val, key) {
if (val != null) {
if (typeof(val) === "object") {
if (Object.keys(val).length > 0) {
filteredObj[key] = val;
}
} else if (typeof(val) === "string") {
if (val.trim() !== "") {
filteredObj[key] = val;
}
} else {
filteredObj[key] = val;
}
}
});
return filteredObj;
};
});
jsFiddle example
You could also use the ng-if directive and a function that parses the objects as you see fit.

Resources