ng-repeat not working properly when using key and value - javascript

In my program iam trying to display the resultant array using ng-repeat with key and value but is not working properly.But the output is displayed correctly in console.
I think its a simple mistake but iam not able to figure it out. Here is the code.
app.controller("taglistcontroller",function($scope,MyService1)
{
var photodetails=MyService1.getProperty1();
var array=[];
angular.forEach(photodetails, function(value1)
{
var sample=value1.tag;
angular.forEach(sample, function(value,key)
{
var tagvalue=value;
var temp=array[tagvalue];
if(temp === undefined)
{
array[tagvalue]=1;
}
else
{
temp++;
array[tagvalue]=temp;
}
});
});
$scope.outputtaglist= array;
console.log(array);
});
html code
<H2>Tag list </H2>
<ul>
<li ng-repeat="(key,value) in outputtaglist">
{{key}} {{value}}
</li>
</ul>

Using (key, value) only works if the object to loop over is a key/value object. In this case you are using an array so it only has value's and an index which you can find in $index
<div ng-repeat="value in outputtaglist">
{{$index}} {{value}}
</div>
Furthermore, it looks like your creating your array as if it's an object(technically it is, but thats not the problem right now..), you might just want to instance it with
var array={};

Related

how to display name of a particular code from a javascript object in angular js and html5

I have a angular controller that has the following array which has 3 values.
controller.medicalInstitues;
I want to take the 4th object in the array with code "AUS". Then further, I want to display the name of only 2 medical institutes with the code as "SYD" and "MEL" within that choosen bject from the parent array.
something like below:
var country = select controller.medicalInstitues.countryCode = "AUS"
var institues = select controller.medicalInstitues.name from country.code="SYD" and "MEL";
now I need to bind these in the UI (Angular).
<span class="code"> {{ controller.institutes.name }}</span>
Suppose you have got your list of values in medicalInstitues, then in the angularjs controller you can do
$scope.institues = medicalInstitues.filter(function(value){
return value.countryCode == "AUS" && (value.code == "SYD" || value.code == "MEL");
});
In HTML you can use ng-repeat:
<div controller="controller">
....
<span ng-repeat="institue in institues">{{institue.name}}</span>
....
</div>
In your controller, to bind the 4th object in your array you can set:
$scope.AUS = yourArray[3]
Then in the html you can show the object properties:
{{ AUS."object path to name" }}
Well, if I understood your question well, you can do the following:
// If you have an array that you already know that will come 4 items with the same country code, you can simply do:
$scope.medicalInstitues = array[3];
// Otherwise:
$scope.medicalInstitues = array.filter(function (value) {
return value.countryCode == "AUS";
})[3];
// To get all 'institues' with the countryCode equals to 'SYD' or 'MEL':
$scope.institues = array.filter(function (value) {
return value.countryCode == "SYD" || value.countryCode == "MEL";
});

Hide graphically some items iterating with ng-repeat

I am developing a web-application using Angular Js.
I want to fill a div, into my html view, using the ng-repeat directive. The array used by ng-repeat has some duplicates, but in my view I want to display item only once (if an element has already been shown, its copies must be graphically hidden). How can I do this?
<div ng-repeat="item in selectedProcedures track by $index">
<span>{{item.id}}</span>
</div>
Just use a unique filter like this:
<div ng-repeat="item in selectedProcedures track by $index | unique : 'id'">
<span>{{item.id}}</span>
</div>
Then create the unique filter:
app.filter('unique', function() {
return function(collection, property) {
var output = [];
angular.forEach(collection, function(item) {
//check if it exists in output on the basis of property, if not then add to output
output.push(item);
})
return output;
}
})
'property' in the function is 'id' in the example whereas collection refers to the entire array.
I would recommend you not to hide generated Html, but to add a filter to delete duplicates :
<div ng-repeat="item in selectedProcedures track by $index | deleteDuplicates">
. . .
</div>
angular.module('myApp').filter('deleteDuplicates', function(){
return function filterCore(source)
{
var out = [];
// . . .
return(out);
};
});
Here is the AngularJS custom filter tutorial.

Conditionally setting orderBy Angularjs

I have an array of users, I want to have my ng-repeat ordered by last name when first loaded. After a new user is added have the ng-repeat ordered by dated added then last name. Essentially I want the newest users pushed to the top of the ng-repeat.
<th ng-click="menuFilter('lastName', 1);">
<div ng-class='{"menuSort":sortColumn==1}'>Name <span ng-show="share.orderByField == 'lastName'">
</div>
</th>
<tr ng-repeat="user in users | orderBy:orderByField:reverseSort"></tr>
In my JS...
_this.sortColumn = 1;
_this.orderByField = 'lastName';
_this.reverseSort = false;
_this.menuFilter = function(section, column) {
_this.orderByField = section;
_this.reverseSort = !_this.reverseSort;
_this.sortColumn = column;
};
//my attempt to reset the order by created at date
if( _this.isRefreshing ) {
_this.orderByField = ['createdAt', 'lastName'];
}
Basically this code is not doing anything. I think I am missing a step in the HTML.
Thanks!
I think this is easiest done by sorting the array in pure javascript and then using a ng-repeat without the orderBy attribute.
HTML:
<div ng-repeat="user in users">{{user}}</div>
<input type="text" ng-model="name"></input>
<button ng-click="addName()">Add name</button>
JS:
$scope.users = ["Rusty", "Shackleford", "Dale", "Gribble"];
$scope.users.sort();
$scope.addName = function() {
$scope.users.unshift($scope.name);
}
JSFiddle: http://jsfiddle.net/asWF9/2/
This answer may help to sort your array: https://stackoverflow.com/a/6712080/3675149
Try using "unshift" instead of 'push' to add an item into the array. The unshift in js enables us to insert an item to the top of an array.

How to use ng-repeat with filter and $index?

I want to use ng-repeat in Angular, while I only want to output some elements of the array. An Example:
ng-repeat="item in items | filter:($index%3 == 0)"
However, this does not work. Please tell me how to do this; only output exact index of elements.
In your code, filter apply on 'items' array, not on each array item, that's why it does not work as you expect.
Instead, you can use ng-show (or ng-if):
<ul>
<li ng-repeat="item in items" ng-show="$index % 3 == 0">{{item}}</li>
</ul>
See: http://jsfiddle.net/H7d26
EDIT: Use ng-if directive if you do not want to add invisible dom elements:
<ul>
<li ng-repeat="item in items" ng-if="$index % 3 == 0">{{item}}</li>
</ul>
Create a custom filter, for example:
filter('modulo', function(){
return function (arr, div, val) {
return arr.filter(function(item, index){
return index % div === (val || 0);
})
};
});
Then change the ng-repeat to:
<ul ng-repeat="item in items | modulo:3">
Or filter by (index % 3 === 1) like:
<ul ng-repeat="item in items | modulo:3:1">
http://jsfiddle.net/Tc34P/2/
What you need to do is find the index of "item" in $scope.items. See below
ng-repeat"item in items | filter:(items.indexOf(item)%3 == 0)
So a real world example (for others who come across this solution) would be.
<div ng-repeat="item in filtered = (items | filter:customfilter | orderBy:customsort)">
<div> This is number {{items.indexOf(item)}} in the items list on the scope.</div>
</div>
The above example will get the correct position regardless of the sorting or filtering
All the precedent answers will work, but if you want to use a filter, you can also define it yourself, like in this fiddle : http://jsfiddle.net/DotDotDot/58y7u/
.filter('myFilter', function(){
return function(data, parameter){
var filtered=[];
for(var i=0;i<data.length;i++){
if(i%parameter==0)
filtered.push(data[i]);
}
return filtered;
}
});
and then call it like this :
ng-repeat='item in items | myFilter:3'
(I added extra complexity with a parameter, if you want to change it quickly to even numbers for example)
Have fun
++
I suggest filtering with a function:
ng-repeat"item in filterItems(items)"
And on the Controller:
$scope.filterItems= function(items) {
var result = {};
angular.forEach(items, function(item) {
// if item is something.. add to result
});
return result;
}
An alternate approach to solving this creates a new "list" (I don't know the proper term in this context) in the ng-repeat. This new list can then be referred to within the scope
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="friend in filteredFriends = ((friends | filter:q:strict) | orderBy:'age')" ng-if="$index % 2 == 0">
[{{$index + 1}}] {{filteredFriends[$index].name}} who is {{filteredFriends[$index].age}} years old.
<span ng-if="$index+1 < filteredFriends.length">[{{$index + 2}}] {{filteredFriends[$index+1].name}} who is {{filteredFriends[$index+1].age}} years old.</span>
</li>
</ul>
The ng-if on the span wrapping the second half prevents the base text from being shown when the previous element is the last element of the list.

Angular factory filter - Can't get data passed to the filter

I'm looking through the Angular docs and I can't better documented stuff.
My problem is as follows:
I have a filter:
.filter('filteringService', function () {
return function (photos, categsList) {
if (photos !== undefined) {
var filteredPosts = [];
console.log('Categories or Selected Categories:');
console.log(categsList);
//DEVEL Only, assign a SEARCH value, can't pass the data from the list now.
categsList = 'people';
if (categsList === undefined) {
for(i=0; i < photos.length; i++) {
filteredPosts.push(photos[i]);
}
} else {
console.log('Trying to push a category slug to search for.');
//TASK: Convert in multiple possible selections.
filteredPosts = [];
}
console.log('Filter returns ' + filteredPosts.length + ' posts');
return filteredPosts;
}
};
});
And I have the template
<div class="photos">
<div class="filters">
<ul>
<li><a>ALL</a></li>
<li ng-repeat="category in categsList">
<a ng-checked="category[0]" ng-model="category[0]">{{ category[1] }}</a>
</li>
</ul>
</div>
<ul class="photos-list">
<li ng-repeat="photo in photos|filteringService:category">
<h1>{{ photo.title }} click LINK</h1>
<ul class="categories">
<li ng-repeat="category in photo.categories">
{{ category.title }}
</li>
</ul>
</li>
</ul>
</div>
There's a huge object with posts called photos and then there's a category list called categsList.
The photos object has the items from the categs list in it. I WANT to be able to filter with the CLICKED element through that list, and maybe multiple filter, but first to pass on the actual filter value to the filter service, I can't seem to do that.
How should I do that?
Apparently I managed to pass the filter value, in a dirty way (I GUESS), like this
<a ng-bind="category.slug" ng-click="returnFilter(category.slug);" ng-model="category.slug">{{ category.title }}</a>
it goes here
$scope.returnFilter = function(theSlug) {
$scope.filterBy = theSlug;
};
and it comes out here
<li ng-repeat="photo in photos|filteringService:filterBy">
It's working, but Is this correct?
EDIT: Also with this way in mind, I could pass an array as theSlug so I can do multiple filtering, and when clicking two times on the same item it would get it out of the array. hmmm
EDIT 2:
Let's say the resulting array is under 15 items, could do I run some action in the controller knowing this?
Actually the other way around, could I query from the controller the resulting array that the filter outputs?
I can't $watch the first array, I guess the filter creates a new array and puts those results in page. How could I watch the resulting array for changes and do stuff in the controller?

Categories