I have JSON array like:
var data = [
{
"name": "Jim",
"age" : 25
},
{
"name": "Jerry",
"age": 27
}
];
in HTML:
<ul>
<li ng-repeat="val in data | filter:{age: age}:true">{{val.name}}</li>
</ul>
The above code is working fine as i want the output, but i don't want to use ng-repeat where it creates loop and then i filter.
is there any another way where i can directly select the DATA from array where age = age ??
Filters can be used in any angular expression (there is nothing ngRepeat-specific about them).
(They can be even used in JavaScript.)
E.g. the following expression displays the data associated with the first user (limitTo:1) that has an age of 25 (filter:{age: 25}), formatted as JSON (json):
{{data | filter:{age: 25}:true | limitTo:1 | json}}
See, also, this short demo.
As mentioned by #link in comments, there is no way to pluck the object with the required age from the array without looping through it. However, you're right in thinking that using ng-repeat here is not appropriate if you only want to display a single object from the array, so ideally the required object should be stored in your controller.
One approach would be to use $filter in your controller instead:
$scope.obj_with_correct_age = $filter("filter")(data, {age: age});
<li>{{ obj_with_correct_age.name }}</li>
I realize this is an old thread but for completeness.
This works:
{{data.Systems[data.Detail.SystemId].System}}
This way, you don't need to filter the data.
If you want to parse single value of name. like {"name":"value"}.
so after $http post, i am assuming that your response in var data= response.
Now find, like console.log(data[0].name);
Here, result will be Jim
Related
By using ng-repeat i'm getting values but i need to sort it in specific order.
that is 'Portfolio', 'Sourcing', 'Delinquency'
can you please help me by providing sorting order.
HTML:
ng-repeat="row in DashboardFilter2" | orderBy: ['Portfolio', 'Sourcing', 'Delinquency']
js:
App.createList({
"qDef": {
"qFieldDefs": %Type
},
"qInitialDataFetch": [
{
"qHeight": 20,
"qWidth": 1
}
],
},function Show2(reply, app){
$scope.DashboardFilter2 = app.field("%Type").getData();
});
ng-repeat looks correct to me.
Would be good to see app.field("%Type").getData() result.
But to be honest, I would not use orderBy with strong reason since it is a filter and evaluates on every $digest/$apply.
Instead, I'd sort as I want in JS before putting it into template using Array.sort or similar method (lodash, underscore).
If the array changes after initialization then just make a function sortArrayYouWant and call every time it changes.
The global idea is NOT TO USE ORDERBY since it is extremely inefficient
I have a set of data like this
$scope.students = [
{ name:"John", courses:["Math", "Physics", "Chemistry"] },
{ name:"Paul", courses:["Economics", "Math", "Sociology"] }
]
I would like a way to filter using angular-filter so that I can get a list of all the subjects without repetition.
I've been trying to use unique filter, but I cannot get it to work since I try to iterate like
<ul ng-repeat="student in students">
<li ng-repeat="x in student.courses | unique:courses"></li>
{{x}}
</ul>
My desired output of the first ng-repeat would be an array like this:
["Math", "Physics", "Chemistry", "Economics", "Sociology"]
so I could iterate through it in the second one.
I have achieved this throught making a new scope with just the desired array, but then I cannot bind it properly, so I would like to achieve it through filtering. Thanks in advance.
I would really recommend you using the libraries Lodash or Underscore for this kind of problems. Learning to master these has helped me a lot!
Of course, you can create your own angular filter using one of them. The method you would like to use is union:
_.union(_.flatten(_($scope.students).pluck("courses")))
I use pluck to get out the courses arrays from the studens object, then I flatten the result (to get rid of the array that it comes nested in), and then i use union to get each subject only once.
If the requirement actually is to:
...get a list of all the subjects without repetition.
Then I would make a separate array for subjects:
$scope.courses = [];
// There are many ways to do skin this cat... (prograde does have a point!)
$scope.students.forEach(function(student) {
student.courses.forEach(function(course) {
if ( $scope.courses.indexOf(course) === -1 ) {
$scope.courses.push(course);
}
})
});
HTML
<ul>
<li ng-repeat="course in courses">
{{ course }}
</li>
</ul>
And if the students change I would recreate the courses-array.
But it sounds as if you are trying to do something else.
But it doesn't give the desired output.
It would help if you tell us what that desired output is!
http://plnkr.co/edit/bZNjIEFznvuyTU3zxAp1?p=preview
I have an AngularJS controller with the following function:
$scope.getExampleValue = function(exampleId) {
// calculate a value using underscore's _.where()
// clause against two JSON arrays on the $scope
// and the exampleId parameter passed in
return computedValue;
}
The function's parameter (exampleId) is rendered from the server, so the resulting HTML looks like this:
<div ng-controller="ExampleController">
...
<span>{{ getExampleValue(3) }}</span>
<span>{{ getExampleValue(4) }}</span>
<span>{{ getExampleValue(5) }}</span>
...
</div>
The problem I have is that AngularJS doesn't know to call getExampleValue() again when the JSON arrays used in the function have changed: they're 2 simple JSON arrays, new JSON items can be added or removed, or properties of existing JSON items in either array can be modified which affect the result.
I've looked at $scope.watch() and $scope.watchCollection() but I'm unsure how I can use them without changing my approach to bind against already computed values rather than against the function I prefer.
Essentially I think I'm asking how to notify AngularJS that a complicated bound value has changed, then I could wrap that notification up in a $scope.watch()..
Thanks for your help.
You are looking for $scope.$apply:
When you change the JSON asyncly, run:
$scope.$apply(function () {
// update the properties on $scope
});
I have a problem with the refresh button in my Angular application:
I have a json object with two arrays in it -> data = {array1: [], array2: []}
I want to loop both arrays and print the related values. To achieve that, I use the Angular ng-repeat directive like this:
ng-repeat="index in [] | index:getTotalNumberOfObjectsInArray1()"
...
<span ng-bind="data.array1[index]"></span>
<span ng-bind="data.array2[index]"></span>`
My Problem is, that on every click on the refresh-button these data will be recreated on the dom.
I learned the documentation about "track by" but i understand it only on objects (for example: ng-repeat="a in objects track by a.id")
How can I use this track by filter for my ng-repeat above, to prevent the recreation of my data?
You can use $index that is defined in a ng-repeat (cf.doc) but you have to have the two array with the same length.
Another solution could be to merge your arrays together and loop on it but I am not sure if it answer to your question.
In almost all the examples of ng-repeat I've seen, the data is structured like so:
$scope.dataCollected = [{name: bob, data: '10-12-12'}, {name:joe, data: '09-13-13'}];
However, the only way I can get ng-repeat to work is if I structure the data like this:
$scope.dataCollected = {bob: {name: bob, data: '10-12-12'}, joe: {name:joe, data: '09-13-13'}};
Structuring it as an array causes the ng-repeat to do absolutely nothing. It doesn't even give an error. Structuring it as an object containing objects works, but I'd like to use an array because I understand it's the only way to use a filter on ng-repeat.
I'm calling the ng-repeat like this:
<div class="list-row" ng-repeat="data in dataCollected">
<h3 class="name"> {{data.name}} </h3>
</div>
What am I missing?
Sorry guys, thank you for the help. The issue was that in an attempt to make my data easier to read, I had assigned names to the keys of the array using bracket notation as seen in the answer here: stackoverflow.com/questions/12244483/… ng-repeat does not like that at all. It seems the default keys are necessary.