Global value or cache for ng-repeat / ngRepeat in AngularJS - angularjs

I'm trying to keep a global value or some sort of cache out of ngRepeat. It is a bit complicated to explain so here is what I'd like to do.
I used the example code from docs:ngRepeat.
<body>
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul>
<li ng-repeat="friend in friends>
{{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
I want to sum up the age value on every repetition. The result should look like this:
John who is 25 years old. 25 - explanation: 25+0
Jessie who is 30 years old. 55 - explanation: 25+30
Johanna who is 28 years old. 83 - explanation: 55+28
Joy who is 15 years old. 98 - explanation: 83+15
...
A Plunkr for experiments can be found here http://plnkr.co/edit/VFiTOnmQ4cyqgNMDa9L4.
Thank you!

You could do something like:
<ul ng-init="ages = []">
<li ng-repeat="friend in friends">
{{friend.name}} who is {{friend.age}} years old.
{{ ages[$index] = (friend.age + ages[$index-1]) }}
- explanation {{friend.age }} + {{ 0 + ages[$index-1]}}
</li>
</ul>
Updated plunker: http://plnkr.co/edit/8XCt3j?p=preview

Related

AngularJS - object values not show in {{}}

I have to show some values from a Json in the {{}} but I see the values just are shown in console and right inside app.controller. Its just going off this app.controller and the values are not shown.
These are some parts of the code:
var app = angular.module('confusionApp',[]);
app.controller('dishDetailController', function() {
var dish={
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
rating:5,
comment:"Imagine all the eatables, living in conFusion!",
author:"John Lemon",
date:"2012-10-16T17:57:28.556094Z"
},
{
rating:4,
comment....
And finishing:
...date:"2013-12-02T17:57:28.556094Z"
},
{
rating:2,
comment:"It's your birthday, we're gonna party!",
author:"25 Cent",
date:"2011-12-02T17:57:28.556094Z"
}
]
};
this.dish = dish;
console.log(dish["name"]); console.log(dish.image); console.log(dish.category);
console.log(dish.label); console.log(dish.price); console.log(dish.description);
console.log("----------------------------------------------------------");
console.log(dish.comments[0]["rating"]); console.log(dish.comments[0]["comment"]);
console.log(dish.comments[0]["author"]); console.log(dish.comments[0]["date"]);
});
console.log("Hey hey hey!");//This shown perfectly in console
console.log(dish.name);//but this is showing... ReferenceError: dish is not defined
And on the view it is not working too...Not is displayed, just blank.
....<img class="media-object img-thumbnail"
ng-src={{image}} alt="Uthappizza">
</a>
</div>
<div class="media-body">
<h2 class="media-heading">{{dish.name}}
<span class="label label-danger">{{dish.label}}</span>....
The ngApp is in html tag:
<html lang="en" ng-app="confusionApp">
And ngController is placed in a div that holds the entire view:
<div class="container" ng-controller="dishDetailController">
So...what's wrong?
You are using Controller as.
Just convert your
<div class="container" ng-controller="dishDetailController">
to
<div class="container" ng-controller="dishDetailController as ctrl">
and access value via ctrl
like this
{{ctrl.dish.name}}
use controller as in the html like this
<div ng-app="confusionApp" ng-controller="dishDetailController as vm">
<img class="media-object img-thumbnail"
ng-src={{vm.image}} alt="Uthappizza">
<div class="media-body">
<h2 class="media-heading">{{vm.dish.name}}
<span class="label label-danger">{{vm.dish.label}}</span>
</div>
var app = angular.module('confusionApp',[]);
app.controller('dishDetailController', function() {
var dish={
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
rating:5,
comment:"Imagine all the eatables, living in conFusion!",
author:"John Lemon",
date:"2012-10-16T17:57:28.556094Z"
},
{
rating:2,
comment:"It's your birthday, we're gonna party!",
author:"25 Cent",
date:"2011-12-02T17:57:28.556094Z"
}
]
};
this.dish = dish;
console.log(dish["name"]); console.log(dish.image); console.log(dish.category);
console.log(dish.label); console.log(dish.price); console.log(dish.description);
console.log("----------------------------------------------------------");
console.log(dish.comments[0]["rating"]); console.log(dish.comments[0]["comment"]);
console.log(dish.comments[0]["author"]); console.log(dish.comments[0]["date"]);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="confusionApp" ng-controller="dishDetailController as vm">
<img class="media-object img-thumbnail"
ng-src={{vm.image}} alt="Uthappizza">
<div class="media-body">
<h2 class="media-heading">{{vm.dish.name}}
<span class="label label-danger">{{vm.dish.label}}</span>
</div>

bootstrap-angular.js comments sorting by order

I want to display the comments in a specific order by typing date, author, and rating in the input section.They should also be able to sorted in descending order, for example, if -date is typed. I'm stuck.
Comments sorting
Here's my code.
<ul class="list-unstyled" ng-repeat="comment in dishDetailCtrl.dish.comments | orderBy:dishDetailCtrl.sortBy">
<li><blockquote>
<h4>{{comment.rating}} Stars</h4>
<h4>{{comment.comment}}</h4>
<footer>
{{comment.author}}, {{comment.date | date:mediumDate}}
</footer>
</blockquote></li>
</ul>
<script>
var app = angular.module('confusionApp',[]);
app.controller('dishDetailController', function() {
var dish={
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
rating:5,
comment:"Imagine all the eatables, living in conFusion!",
author:"John Lemon",
date:"2012-10-16T17:57:28.556094Z"
},
{
rating:4,
comment:"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
author:"Paul McVites",
date:"2014-09-05T17:57:28.556094Z"
},
{
rating:3,
comment:"Eat it, just eat it!",
author:"Michael Jaikishan",
date:"2015-02-13T17:57:28.556094Z"
},
{
rating:4,
comment:"Ultimate, Reaching for the stars!",
author:"Ringo Starry",
date:"2013-12-02T17:57:28.556094Z"
},
{
rating:2,
comment:"It's your birthday, we're gonna party!",
author:"25 Cent",
date:"2011-12-02T17:57:28.556094Z"
}
]
};
this.dish = dish;
});
</script>
Above code seems to be working, I think the you missed to write ng-model variable name incorrectly of SortBy input.
It should be
ng-model="dishDetailCtrl.sortBy"
instead of
ng-model="sortBy"
HTML
<div ng-controller="dishDetailController as dishDetailCtrl">
Sort By <input type="text" ng-model="dishDetailCtrl.sortBy">
<ul class="list-unstyled" ng-repeat="comment in dishDetailCtrl.dish.comments | orderBy:dishDetailCtrl.sortBy">
<li>
<blockquote>
<h4>{{comment.rating}} Stars</h4>
<h4>{{comment.comment}}</h4>
<footer>
{{comment.author}}, {{comment.date | date:mediumDate}}
</footer>
</blockquote>
</li>
</ul>
</div>
Demo Plunkr
<div class="col-xs-9 col-xs-offset-1">
<div class="container">
<div class="row">
<div class="col-xs-2">Customer Comments</div>
<div class="col-xs-3-offset-1">
Sort by<input type="text" ng-model="dishDetailControllerSortBy" value=" ">
</div>
</div>
<div class="media-list" ng-repeat="cmnt in dishCtrl.dish.comments | orderBy:dishDetailControllerSortBy">
<div class="media">
<blockquote>{{cmnt.comment}}
<footer>
{{cmnt.author}},{{cmnt.date | date:format:mediumDate}}
</footer></blockquote>
</div>
</div>
</div>
</div>
<input ng-model="userInput"> </input> </p>
<blockquote ng-repeat="comment in dishCtrl.dish.comments | orderBy:userInput">
{{comment.rating}} Stars
{{comment.comment}}
<footer>{{comment.author}} {{comment.date | date:'medium'}}</footer>
</blockquote>

ng-repeat variable scope to the DOM block

Am I dreaming or I really saw that somewhere, but I can't remember the exact syntax. So if I have
var fooObjects = [{ name:"John", age:15 },
{ name: "Michael", age:26 },
...etc...]
and
<div ng-repeat="for foo in fooObjects"> <-- note, this isn't real syntax
{{name}} <-- Now you don't have to explicitly call `foo.name`
{{age}} inside of this div block
</div>
An example from https://docs.angularjs.org/api/ng/directive/ngRepeat. Try something like this:
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul>
<li ng-repeat="friend in friends">
{{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
Here's a plunker with the example http://plnkr.co/edit/I19oBk20T5ldLZe7GYqN?p=preview
--edit--
I misunderstood your earlier question. You could go about aliasing the variable in the ng-repeat by implementing the following in your controller:
$scope.scopify(scope, object) {
for (var o in object) {
scope[o] = object[o];
}
}
Used like the following:
<li ng-repeat="friend in friends" ng-init="scopify(this, friend)">
{{name}}, {{age}}, {{gender}}
</li>
Here is a plunker with a working example: http://plnkr.co/edit/Y8c4uOagcdM5cXN81TET?p=preview
In addition to the above example, you can create aliases for any of the properties of an object through the ng-init directive. For example, another possible solution could be this:
<li ng-repeat="friend in friends"
ng-init="name = friend.name; age = friend.age; gender = friend.gender">
{{name}}, {{age}}, {{gender}}
</li>
We can use ng-init to create aliases that we can reference in that html block. While this is not very useful if you are only going to reference each property once, it might come in handy if you have to repeat the same property multiple times within a block of html.

does ng-repeat create multiple instances of a variable?

I've created this plunker in the form of a 'ToDo' list. My purpose is to fulfill just what it looks like.
Click an item and it will become 'marked' complete. However I am seeing a weird occurrence happen and that is when I change the 'visible' variable to true or false on click, it only effects the list item in the ng-repeat. Conversely, in my 'ToDo' list without ng-repeat the behavior works as expected (though not as desired).
Why does it function this way?
(also the select element at the bottom would work, however it breaks the 'marking complete' by switching the value of 'visible' when I don't actually want it to, any ideas on that would be helpful as well)
http://plnkr.co/edit/uiirZNV5yyBuB5XLst6y?p=preview
<h2>using ng-repeat:</h2>
<div ng-init="peeps = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]"></div>
<ul ng-init="visible = true">
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}" ng-repeat="peep in peeps">{{peep.name}}</li>
</ul>
<h2>NOT using ng-repeat:</h2>
<div>
<ul ng-init="visible = true">
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[0].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[1].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[2].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[3].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[4].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[5].name}}</li>
</ul>
this is because ng-repeat creates its own scope for each item,
you need to access parent scope via $parent
ng-repeat also gives you access to elemnt index in the array,
so your code may look like
ng-repeat="(i, peep) in peeps"
...
ng-click="$parent.peeps[i].visible = !$parent.peeps[i].visible"

How do I render tree structure data by using directive's template

Have anyone tried to render tree structure data by using directive?
What I wanted to do is rendering the data like...
{
name: "root",
next: null,
child: {
name : "1"
next : {
name : "2",
next : {
name: "3",
next: null,
child: null
},
child: {
name: "2-1",
next: null,
child: null
}
},
child: {
name: "1-1",
next: {
name: "1-2",
next: null,
child: null
},
child: null
}
}
}
to HTML data like
<ul>
<li> root
<ul>
<li> 1
<ul>
<li> 1-1 </li>
<li> 1-2 </li>
</ul>
</li>
<l1> 2
<ul>
<li> 2-1 </li>
</ul>
</li>
<li> 3 </li>
</ul>
</li>
</ul>
I know if data is an array, I can use "ng-repeat" for template,
and also if data is an object I know the structure, I can use "{{ }}" tag.
But I don't have any idea for treating object data will change dynamically.
That means I also want to add some child to the data as one object in $scope,
and render it synchronously using angular.js .
Does anyone have a great idea or the experience you did it?
angularjs
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="friend in friends | filter:q">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
result
[1] John who is 25 years old.
[2] Jessie who is 30 years old.
[3] Johanna who is 28 years old.
[4] Joy who is 15 years old.
[5] Mary who is 28 years old.
[6] Peter who is 95 years old.
[7] Sebastian who is 50 years old.
[8] Erika who is 27 years old.
[9] Patrick who is 40 years old.
[10] Samantha who is 60 years old.

Resources