ngFor custom index increment Angular - html

How can I use custom index increment or decrement in ngFor?
I want something like this:
`<div *ngFor="let item of items; let i = index">
<span>
{{items[i].name}}
</span>
<span>
{{items[i+1].name}}
</span>
<!-- Then I want to increment index value like i++ -->
</div>`
I mean how can I use custom for loop in angular's component html file?

I guess what you want to achieve is something like:
<div>
<span *ngFor="let item of items">
{{item.name}}
</span>
</div>
This way you don't have to increment anything - angular ngFor directive does it for you
Update I'm not sure what do you want to achieve - maybe try to describe it in a better way. Maybe try this:
<div>
<p *ngFor="let item of items; let i = index">
<span>{{item.name}}</span>
<span>{{items[i + 1].name}}</span>
</p>
</div>

Related

How can I set the id of an element, which is created by ngFor?

I have created some elements:
<span *ngFor="let versuch of versuche">
<div id="titleId[versuch]"><br></div>
</span>
titleId is a list of strings, where my element-ids are stored).
But if I try to get access to the elements, with document.getElementById('__title__5'), the element is not found (__title__5 is one of the element id's).
So do you know a way to set the id's per code?
Use [id] instead of id as in the example below:
<span *ngFor="let versuch of versuche">
<div [id]="titleId[versuch]"><br></div>
</span>
Use index from the *ngFor. Try the following
Option 1 - titleId is an array of strings
<span *ngFor="let versuch of versuche; let i=index">
<div attr.id="{{titleId[i]}}"><br></div>
</span>
Option 2 - titleId not used
If you need to have corresponding id's based on the index of the versuche variable, you can skip the variable titleId and do it directly in the template.
<span *ngFor="let versuch of versuche; let i=index">
<div [attr.id]="'__title__' + i">{{versuch}}<br></div>
</span>
Option 3 - titleId is an object
If the titleId is an object with keys corresponding to each versuche, then the following should work
component
versuche = [ 'versuche_1', 'versuche_2', 'versuche_3' ];
titleIdObj = {
'versuche_1': '__title__1',
'versuche_2': '__title__2',
'versuche_3': '__title__3',
}
template
<span *ngFor="let versuch of versuche">
<div attr.id="{{titleIdObj[versuch]}}">{{versuch}}<br></div>
</span>
Working example: Stackblitz
ngAttr for binding to arbitrary attributes AngularJS
For example, considering this template
<span *ngFor="let versuch of versuche">
<div ng-attr-id="{{ 'titleId-' + versuch }}"><br></div>
</span>
Doc - https://docs.angularjs.org/guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes
Angular
<li *ngFor="item of items" #elem [attr.id]="item.id">
{{ item.name}} ID: {{elem.id}}
</li>

New Line in SPAN

I am returning below sample value from API and binding it in span element.What I am trying to achieve is to Keep every Unit in separate new line/
"Unit1-Employee1 , Unit2- Employee 2, Unit3- Employee 3,Employee 4"
I have tried to append \n before every Unit in API and bind it to span but it is not starting in new line.
Try this code.
const string = "Unit1-Employee1 , Unit2- Employee 2, Unit3- Employee 3,Employee 4";
const array = string.split(",");
In HTML:
<span *ngFor="let data of array">
{{data}} <br>
</span>
Demo Link:https://stackblitz.com/edit/angular-5ylntb
Push these units in an array and iterate over these items and display each item in span and put a <br> after each <span>. Like shown below:
<span *ngFor="let item of arr">
{{item}} <br>
</span>
Working Demo : link
I'm assuming you will be storing each elements in an array.
Now, iterate through the array as follows.
<span *ngFor="let item of items" style="display:block">
{{item}}
</span>
Or, Simply put it inside div
<div *ngFor="let item of items">
{{item}}
</div>

Is there a way to use iteration inside an object in html in angular?

Here's how my html code is looking:
<div *ngFor="let historyArticle of historyArticles; let i=index">
<div [innerHTML]='historyArticle[i].fields.text | mdToHtml'></div>
</div>
I want to target the every object inside the historyArticle array. Writing {{i}} inside a div gives me the index number for each entry but I want to use that to target the correct text field in each entry
You don't need the i index at all in this case. historyArticle itself is the object you want:
<div *ngFor="let historyArticle of historyArticles">
<div [innerHTML]='historyArticle.fields.text | mdToHtml'></div>
</div>
Using *ngFor in Angular is basically looping through an array.
So doing :
for (let i = 0; i < this.historyArticles.length; i++) {
// do something e.g console.log(this.historyArticles[i].fields.text);
}
Is pretty much the same as :
<div *ngFor="let historyArticle of historyArticles">
<span>{{ historyArticle.fields.text }}</span>
</div>
Hope it helps you understand that in this case you don't need to use i = index
try this.
<div *ngFor="let historyArticle of historyArticles; let i=index">
<div>{{historyArticle[i].fields.text | mdToHtml}}</div>
</div>

display multiple nested data with angular6

I'm receiving JSON data from an API which has some child objects as well. The API has a menu level and down the menu, it's having meals. What I want to do is to display meals relating to each menu under the menu
JSON from API
[{"id":6,"name":"Menu 1","serveDate":"2019-05-10","meals":[{"id":13,"name":"Rice with Stew","description":"rice","image":"","mealType":"BREAKFAST","unitPrice":5,"status":"ENABLED"}]},{"id":5,"name":"Menu 2","serveDate":"2019-06-10","meals":[{"id":13,"name":"Corn Flakes,"description":"Flakes","image":"","mealType":"BREAKFAST","unitPrice":5,"status":"ENABLED"}]},{"id":4,"name":"Menu 3","serveDate":"2019-07-10","meals":[]}]
HTML
<div *ngFor="let item of menuList">
<h2>Menu</h2>
{{item.name}} - {{item.servate}}
<h2 *ngFor="let item of menuList.meals">Meals</h2>
{{item.name}} - {{item.mealType}}
</div>
JS
getMenus() {
this.menuServices.menuList(this.pagedData)
.subscribe(
response => {
if (response && response.code === HttpStatus.OK) {
this.menuList = response.data;
}
},
);
}
Any help on how to make this work correctly the way it should work?
<div *ngFor="let menu of menuList">
<h2>Menu</h2>
{{menu.name}} - {{menu.servate}}
<h2>Meals</h2>
<ng-container *ngFor="let meal of menu.meals">
{{meal.name}} - {{meal.mealType}}
</ng-container>
</div>
Using this way you don't have to add unnecessary divs or any other html tag for looping in angular.
this is the perfect way to do nested loops without changing your html
No need to access the main list as you have your meals array in the item object.
Change HTML Code to:
<div *ngFor="let item of menuList">
<h2>Menu</h2>
{{item.name}} - {{item.servate}}
<h2>Meals</h2>
<div *ngFor="let item of item.meals">
{{item.name}} - {{item.mealType}}
</div>
</div>
When you're doing something like let item of menuList that means the item variable should be used to refer to an individual item within your loop. To avoid confusion, I'd also recommend naming these item vars for nested loops differently.
Another important thing to keep in mind that all the markup that you want to be output for each array item should be wrapped with an element with *ngFor. It's not the case with your <h2> tag being printed for each meal, but not the meal description.
Edit the template as follows:
<div *ngFor="let menuItem of menuList">
<h1>Menu</h1>
<h2>{{menuItem.name}} - {{menuItem.serveDate}}</h2>
<p>maybe description here</p>
<h3>Meals</h2>
<p *ngFor="let mealItem of menuItem.meals">{{mealItem.name}} - {{mealItem.mealType}}</p>
</div>

Can you use a ngFor with a modulus operator in Angular 2

I'm writing out images to the web page. Every three images I would like to start a new row. Does angular 2 support this?
You can achieve it by doing following:
<div *ngFor="let t of temp(math.ceil(arr.length/3)).fill(); let i = index" class="row">
<div *ngFor="let item of arr.slice(3*i,3*i + 3);" class="item">
{{item}}
</div>
</div>
And in your component:
export class App {
temp = Array;
math = Math;
arr= [1,2,3,4,5,6,7,8,9,10,11];
}
Here's working Plunker
You can access the index of the iteration from the *ngFor like so:
*ngFor="let x of container; let i = index;"
you can then reference that index in an *ngIf inside of the *ngFor to display your new row:
<div *ngIf="i%3 === 0">
Borrowing from both answers, but leaning more on Alex's, here's how I accomplished it in ng2 (v2.0.1).
<template ... is deprecated. Where you see <template ... you should use <ng-template ... after v5.
<template ngFor let-peer [ngForOf]="peers" let-p="index" let-last="last">
<div class="row" *ngIf="p % 2 === 0">
<div class="col-xs-8 col-sm-6">
<label><input type="checkbox" ... {{peers[p].name}}</label>
</div>
<div class="col-xs-8 col-sm-6" *ngIf="!last">
<label><input type="checkbox" ... {{peers[p+1].name}}</label>
</div>
</div>
</template>
Note that while I get each item from the collection, let-peer [ngForOf]="peers", I don't specifically use it. Instead I use the collection and the index, let-p="index", adding to the index as needed, e.g., peers[p] and peers[p+n].
Adjust your modulus as needed. The last row should check to be sure that the first column to the last column is not the last item in the iterable.