Get index of outer *ngFor in nested *ngFor - html

I am trying to get the index of the outer *ngFor in the nested *ngFor. Attaching the code below:
<div *ngFor="let st of s;let i = index">
<span *ngFor="let indexnumber of i"> </span> //i is the index of above *ngFor
</span>
{{st}}
</div>
What I get on doing this is an error: Cannot find a differ supporting object '1' of type 'number'. NgFor only supports binding to Iterables such as Arrays.
How can I achieve this scenario?

Related

Display key and array values using *ngFor in angular 9

JSON
{
"cars":
{
"12345": [1960, 1961, 1962],
"4567": [2001, 2002]
}
}
HTML
<strong>Plate and year</strong>
<div *ngFor="let list of lists">
{{list.cars}}
</div>
I need to display like this:
Plate and year
12345- 1960, 1961, 1962.
4567- 2001, 2002.
Based on your data structure, you can achieve this using the KeyValuePipe and additional nested *ngFor. KeyValuePipe allows you to iterate over an object similar to Object.entries providing a key and value property for each item. In this case the value will be an array that you can iterate over using an *ngFor:
<strong>Plate and year</strong>
<div *ngFor="let list of lists">
<div *ngFor="let car of list.cars | keyvalue">
<div>{{car.key}} - <div *ngFor="let year of car.value">{{year}}</div>
</div>
</div>
</div>
Here is an example in action.
Hopefully that helps!

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>

How to display nested array object in angular api call

<div *ngFor="let item of category">
{{item.categories.categories.id}}
</div>
That's the data fetched from api. By nested array I can't display this data
How about this
<div *ngFor="let item of category">
<div *ngFor="let subItem of item.categories">
{{subItem.categories.id}}
</div>
</div>
Explanation:
As there are nested array, you have to loop over again for inner array

Reference ngFor value in component

I have a nested ngFor statement. I need to retrieve the value of my first ngFor on button click.
I have tried the following:
use template reference variable
use attribute binding
use Input decorator
This is my code:
<mat-expansion-panel *ngFor="let item of Datasource;">
<mat-expansion-panel-header style="display:flex" class="mat-row">
{{item.Header}}
</mat-expansion-panel-header>
<mat-selection-list [(ngModel)]="selectedOptions">
<mat-list-option *ngFor="let line of item.match; let i= index;" [value]="line">
<div class="container-name">
<div class="col-6">{{i}} - {line.user.Name }} vs {{ line.user.Address }}</div>
</mat-list-option>
</mat-selection-list>
<div style="text-align:center; padding: 20px">
<button mat-raised-button color="primary" (click)="submit()" type="submit">Add</button>
</div>
</mat-expansion-panel>
Can this be achieved?
Well, you need to clone that object properties first. As that object is linked to the template, when you manipulate it, it is manipulated on template too. You can use var obj = Object.assign({}, actual obj) and then do the manipulation on obj instead of actual one. Then it will not get affected in template. Hope it helps.

Getting keys and values from json in Angular

I need to get values from json (comes from merged MySQL tables).
I've tried a several solutions from previous topic but none of them worked for me.
access key and value of object using *ngFor
my JSON format is:
[
{
"idemployee":1,
"name":"Ernest",
"surename":"Pająk",
"role":"Obsługa Baru",
"employeehours":[
{
"idemployeehours":1,
"date":"2019-01-10T23:00:00.000+0000",
"quantity":8.0
}
]
}
]
and what I got is "Key: 0 and Value: " (answer from Pardeep Jain topic above)
EDIT:
this is my code:
<div *ngFor="let item of employee| keyvalue">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
employee comes from Angular component and gives mentioned JSON. The problem is getting nested values from "employeehours" (like quantity)
You don't need the keyvalue pipe. employeehours is an array, so you just need a nested *ngFor for the array, so example where you have stored your data in an employees array:
<div *ngFor="let emp of employees">
<p>Name: {{emp.name}} {{emp.surename}}</p>
<div *ngFor="let hour of emp.employeehours">
<p>Date: {{hour.date | date: 'shortDate'}}</p>
<p>Quantity: {{hour.quantity}}</p>
</div>
</div>
DEMO
if you run keyValue pipe on array object you got the keys as the index of the values in the array so tha why you need a nested ngFor to run keyvalue pipe on the value of the array
<div *ngFor="let item of employee">
<div *ngFor="let emp of item |keyvalue ">
Key: <b>{{emp.key}}</b> and Value: <b>{{emp.value}}</b>
</div>
</div>
demo 🔥🔥
UPDATED!
if you want to support sohow keys value of employeehours where the value is array best cases here to create a component to do all of this and use this component to render the new values like recursion
component
export class RenderComponent {
#Input() items = [];
isArray(value) {
return value instanceof Array
}
}
template
<div *ngFor="let item of items">
<div *ngFor="let obj of item | keyvalue " class="well">
Key: <b>{{obj.key}}</b> and Value: <b>{{obj.value}}</b>
<ng-container *ngIf="isArray(obj.value)">
<render [items]="obj.value"></render>
</ng-container>
</div>
</div>
demo 💣💣