How to iterate over arrays in angular 12? - arrays

I am trying to iterate over an object that's in an array of an array, however, I'm not able to display the data in the front-end.
I tried this method:
<div *ngFor="let item of events of event | keyvalue">
{{item.key}}:{{item.value}}
</div>
and this one:
<div *ngFor="let item of events of event | json">
Test: {{item}}
</div>
The structure of the JSON data is given in this format.
[
[
{
"age": "age3",
"gender": "gender3"
},
{
"age": "age3",
"gender": "gender3"
}
]
]

You'll have to iterate through each internal array as well, so you'll need a nested *ngFor. Make sure to reference the correct item array in your nested *ngFor.
<div *ngFor = "let item of events">
<div *ngFor = "let x of item">
{{x.age}}:{{x.gender}}
</div>
</div>

It looks likes a nested array, try using multiple ngFor:
<div *ngFor="let event of events">
<div *ngFor="let item of event">
Test: {{item | json}}
</div>
</div>
Otherwise you could try using Array.prototype.flat to flatten the nested array:
this.flattened = this.events.flat();
// ...
<div *ngFor="let item of flattened">
Test: {{item | json}}
</div>

<ng-container> is fine when you want structural logic without polluting the DOM with useless elements.
<ng-container *ngFor="let subArray of array"> <!-- This does not appear in the DOM -->
<div *ngFor="let item of subArray"> <!-- This appears in the DOM -->
{{item.key}}:{{item.value}}
</div>
</ng-container>

Related

Angular 4 ngFor looping through array of objects with HTML

I'm using Angular 4 and I want to loop through an array of objects and display the information in Angular Material grids tiles. My html (app.component.html) looks a bit like this
<div class="list" *ngIf="listContacts == true">
<mat-grid-list cols="3" rowHeight="2:1" *ngFor="let i of contacts">
<mat-grid-tile>
<div class="card">
<img src={{contacts[i].image}} alt="picture">
<h2>{{contacts[i].name}}</h2>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
And contacts is an array of objects inside app.component.ts. There are NINE objects within contacts but for simplicity I've only put two here.
export class AppComponent {
// array of contact objects
contacts = [
{
name: "Robbie Peck",
image: "src/assets/robbie.jpg",
},
{
name: "Jenny Sweets",
image: "src/assets/jenny.jpg",
},
...
]
}
So rather than have nine different 's appear, each with their own information (looping i through contacts), I only have one and the console shows an error where it doesn't recognize contacts[i]. What have I done wrong? How can I get the to have 9 's, each with name and image i within the contacts object in the typescript (app.component.ts) file?
You don't have to pass the index, you can just use the variable i and access i.image and i.name
<mat-grid-list cols="3" rowHeight="2:1" *ngFor="let i of contacts" >
<mat-grid-tile>
<div class="card">
<img src={{i.image}} alt="picture">
<h2>{{i.name}}</h2>
</div>
</mat-grid-tile>

Showing JSON-data in AngularJS

This is how my JSON-data looks like:
var data = [
"val1":[
{"DATE":a1, "HEADER":b1, "MESSAGES":c1},
{"DATE":a2, "HEADER":b2, "MESSAGES":c2},
{"DATE":a6, "HEADER":b6, "MESSAGES":c6},
],
"val2":[
{"DATE":a5, "HEADER":b5, "MESSAGES":c5},
{"DATE":a8, "HEADER":b8, "MESSAGES":c8},
],
"val3":[
{"DATE":a3, "HEADER":b3, "MESSAGES":c3},
{"DATE":a4, "HEADER":b4, "MESSAGES":c4},
{"DATE":a7, "HEADER":b7, "MESSAGES":c7},
],
];
Now I want to use this data in html. Therefore I use AngularJS (although this is an old framework). The data is correctly sended to the client side but now I have to display it correctly. I already have this:
<ul>
<li class="message" ng-repeat="messages in data">
{{ messages }}
</li>
</ul>
Now it's showing all the data (which isn't my goal). It should be like this:
Each value (like "val1" and "val2" etc.) should be displayed. Therefore i use ng-repeat.
But now I also want to show the data inside. I thought that I could make another ng-repeat to display all the values of the arrays inside "val1" etc.
But how could I do this and have access to those values?
This HTML should display every item inside val1 array, val2 array and so on:
<ul>
<li class="message" ng-repeat="messages in data">
<span ng-repeat="item in messages">
{{ item }}
<span>
</li>
</ul>
The line <li class="message" ng-repeat="messages in data"> will repeat 1'st level arrays inside data array, and
<span ng-repeat="item in messages">
{{ item }}
<span>
will iterate and display every 2'nd level item, such as {"DATE":a1, "HEADER":b1, "MESSAGES":c1} and so on.

Angular js Asocciative array ng repeat

i have an angular js array binded to the $scope object. The array is an associative array. Simple array of arrays, and i dont know how to traverse through it in ng-repeat. This is my array, and I want to get the path of each file which on 0th index in sub arrays. I want to get
files/file/img1.bmp,
files/file1/img1.jpg,
files/file2/img1.jpg
$scope.im = [
["files/file/img1.bmp", "files/file/img2.jpg", "files/file/img3.jpg", "files/file/img4.jpg", "files/file/img5.jpg", "files/file/img6.jpg", "files/file/img7.jpg", "files/file/img8.jpg", "files/file/img9.jpg"],
["files/file1/img1.jpg", "files/file1/img2.jpg", "files/file1/img3.jpg", "files/file1/img4.jpg", "files/file1/img5.jpg", "files/file1/img6.jpg", "files/file1/img7.jpg", "files/file1/img8.jpg", "files/file1/img9.jpg"],
["files/file2/img1.jpg", "files/file2/img2.jpg", "files/file2/img3.jpg", "files/file2/img4.jpg", "files/file2/img5.jpg", "files/file2/img6.jpg", "files/file2/img7.jpg", "files/file2/img8.jpg", "files/file2/img9.jpg"]
];
Not really an associative array cause you got no key for your values.
However, given your code if you want to iterate over your array just use :
<div ng-repeat="file in im">
<!-- Now file is your list (e.g. ["files/file/img1.bmp", "files/file/img2.jpg"] -->
<p>{{file[0]}}</p>
<p>{{file[1]}}</p>
<!-- and so on -->
</div>
And you will get the first element of each one of your items in the array.
Displaying image out of those nested array could be simple, here is an example:
<div ng-repeat="childArray in im">
<div ng-repeat="photos in childArray">
<img src="{{items}}" alt="something" />
</div>
</div>
Try this. As #Priyesh Kumar commented so you should use nested ng-repeat
<div ng-repeat="key in im">
<div ng-repeat="value in key">
{{value}}
</div>
</div>
You can iterate over the array, im, normally as described in the docs and access the first element of your inner array
<ul>
<li ng-repeat="list in im">
<!--- list now represents the inner array --->
{{ list[0] }} <!-- write the first path -->
</li>
</ul>
If you want it to work for each index of the sub arrays:
<div ng-repeat="(idx, value) in im[0]">
<br>
<div ng-repeat="file in im">
<p>{{file[idx]}}</p>
</div>
</div>
This would print :
files/file/img1.bmp
files/file1/img1.jpg
files/file2/img1.jpg
files/file/img2.jpg
files/file1/img2.jpg
files/file2/img2.jpg
...

Significance of ng-repeat-start vs ng-repeat

I am trying to understand the significance of ng-repeat-start over ng-repeat. The angular documentation provides the following example for ng-repeat-start
<header ng-repeat-start="item in items">
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer ng-repeat-end>
Footer {{ item }}
</footer>
But the same can be achived using ng-repeat,
<div ng-repeat="item in items">
<header>
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer>
Footer {{ item }}
</footer>
</div>
Can someone explain the significance of ng-repeat-start.? Thanks.
I thought I'd add my answer, as no one touched on a very important reason for having these directives available. ng-repeat will not work correctly in certain scenarios when using html tables. Using ng-repeat-start is the only way to accomplish certain things.
Imagine you want to display your data like this using html tables:
And this is your data set:
groups = [
{
name: "Group 1",
customers: [
{id: 123, name: "Foo Inc.", state: "NJ"},
{id: 234, name: "Bar Co.", state: "AZ"}
]
},
{
name: "Group 2",
customers: [
{id: 345, name: "Baz LLC", state: "CA"}
]
}
];
Using ng-repeat-start and ng-repeat-end you can do this:
<table>
<tr>
<th>ID</th>
<th>Customer</th>
<th>State</th>
</tr>
<tr ng-repeat-start="group in groups">
<td colspan="3" style="text-align:center">{{group.name}}<td>
</tr>
<tr ng-repeat-end ng-repeat="customer in group.customers">
<td>{{customer.id}}</td>
<td>{{customer.name}}</td>
<td>{{customer.state}}</td>
</tr>
</table>
Notice the ng-repeat-end followed by another regular ng-repeat. This ends the matching ng-repeat-start but initiates another repeat on the customers array, since we are still in the original ng-repeat-start scope when calling ng-repeat-end, we still have access to the group object.
Keep in mind, this is a very trivial example, but as the table structure becomes more complicated, the only way to accomplish things like this is to use ng-repeat-start and ng-repeat-end
The significance of these two directives is similar: they repeat HTML-tags. The difference is only that with help of ng-repeat-start you could repeat few tags starting from tag with ng-repeat-start and finishing by ng-repeat-end.
For example you have next code:
<div>
Item # {{item}}
</div>
<div>Whether you repeat me?</div>
So now we can add 2 directives for these code.
With ng-repeat:
<div ng-repeat="item in items">
Item # {{item}}
</div>
<div>
This code will not be repeated
</div>
With ng-repeat-start and ng-repeat-end:
<div ng-repeat-start="item in items">
Item # {{item}}
</div>
<div ng-repeat-end="">This code will be repeated</div>
So now you can see that in the first case just div with ng-repeat directive repeats, but in the second case both your divs will be repeated.
You can see Demo and play with it:
Demo: http://plnkr.co/edit/R778lWTABVF3Hy16CAca
The ng-repeat-start directive works the same as ng-repeat, but will repeat all the HTML code (including the tag it’s defined on) up to and including the ending HTML tag where ng-repeat-end is placed

Extract specific element from ng-repeat

I have a list where I display the content of a list using angularjs, like this:
<ul>
<li ng-repeat="result in uploadLogObject[fileUpload.id].log track by $index">
<ul>
<div data-ng-show="result">{{result}}</div>
</ul>
</li>
</ul>
This means that I get a list like this:
* Some data1
* Some data2
* Some data3
* Some data4
Is it possible to take e.g the first element of the list and place outside of the list so that my list is displayed like this?
Some data1
* Some data2
* Some data3
* Some data4
I would guess you would have to do a separate ng-repeat="result in uploadLogObject[fileUpload.id].log track by $index" before the ng-repeat with the list and then display the first content somehow like this? <div data-ng-show="result">{{result}}[0]</div>
Am I wrong or on the right track here?
The documentation of ngRepeat provides a way to do this using ng-repeat-start and ng-repeat-end. :
<div ng-repeat-start="item in items" ng-if="$first">
Header {{ item }}
</div>
<li ng-repeat-end>
body {{ item }}
</li>

Resources