How to run a *ngFor loop inside other loops - arrays

I get a lot of data coming from an API, and among that data, I have these images:
Photos: "uploads/60bcb8f0244b2.png,uploads/60bcb8f025427.png"
I used *ngFor to present all the data that exists, "Photos" is one of them. My question is, how can I separate the link from this "Photos" field? Note that it currently has a comma separator. I can't use split(',') inside *ngFor. What would be the solution?

You can try split(",") as below
<ul>
<li *ngFor="let item of data">
{{item.text}}
<div *ngFor="let p of item.photos.split(',')">
{{p}}
</div>
</li>
</ul>
Here is example for you: https://stackblitz.com/edit/angular-ivy-i92axf?file=src/app/app.component.html

Related

transforming data returned from firebase

What I'm trying to do: receive data from fire base, and display some values from that data to the screen.
How I've gone about doing it: I have created an Angular SPA and the data I return from Firebase is as follows:
Returned Data from Firebase
Error I'm receiving:
I then use an *NgFor loop in the html portion of the component as follows:
<div class="row">
<ul class="list-group" *ngFor = "let guardian of guardians">
<li class="list-group-item">{{ guardian.firstname }}</li>
</ul>
</div>
ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed.
I have looked for solutions to this and the common answer is to transform the received data into an array. I have attempted to do that with the following:
for (const guardian in data) {array.push(guardian);}
However, the array I receive back is missing all of my values. It comes back in this form:
["-L3n95t-rxA4-bOgc8fz", "-L3nF0h5EEKtwAiZv0Q7",
"-L3oWoBmoXK3-5XBkx9i", "-L3oWxEhAcUGQX2P4yES", "-L41_cK3KD6DMduhG3P3",
"-L4CbTtNqGuVyT3hzY-R", "-L4CfKsBxfQxSKd2PR4s", "-L4EDFkbsWMrT61fLjhD"]
This allows me to use my *NgFor statement, but this data is useless to me now. Any knowledge on how to transform this data?
After three days of banging my head against this one any help is appreciated! :)
The data in that array is actually each key within the guardians object. Now what you want to do is utilize those keys. Lets assume you gave your key array a value such as this.guardianKeys = array
Then you can iterate through the keys and access the original guardians objects like so:
<div class="row">
<ul class="list-group" *ngFor = "let key of guardianKeys">
<li class="list-group-item">{{ guardians[key].City }}</li>
<li class="list-group-item">{{ guardians[key].Phone }}</li>
<li class="list-group-item">{{ guardians[key].State }}</li>
...
</ul>
</div>
This solution solved my problem.
for (const guardian in data) {array.push(data[guardian]);}
by pushing this into an empty array I was then able to iterate through the array with *NgFor.

ngRepeat weird behaviour

I can not believe that i am unable to do the simple following object made up of two arrays
{"M":
[
"Alpha",
"Beta",
"Zeta"],
"F":
[
"Alpha",
"Omega"
]}
All i want to do is have a nested ng-repeat like the following
<a
class="list-group-item list-group-item-info"
ng-repeat="(key,list) in vm.result">
{{key}}
<a
class="list-group-item"
ng-repeat="name in list">
{{name}}
</a>
</a>
any one has any idea why it does not work.
It shows the key properly, but fails to iterate in the list and hence the name is not shown and no errors are shown in the console either
thanks
bottom line of your problem:
https://www.w3.org/TR/html401/struct/links.html#h-12.2.2
nested links are illegal
Links and anchors defined by the A element must not be nested; an A element must not contain any other A elements.
Since the DTD defines the LINK element to be empty, LINK elements may not be nested either.
Change your outer element to a <div> or <span> and it works

show images in disorder by the ng-repeat in angularjs

you can see part of my code:
<ul>
<li ng-repeat="commentItem in comments track by $index">
<div style="float: left; width: 15%;;">
<img width="100%" src="{{commentItem.headImage}}">
</div>
</li>
</ul>
<ion-infinite-scroll ng-if="comment.loadMore" on-infinite="loadMoreComments()">
</ion-infinite-scroll>
when the 'comments' contains less data ,all looks normal.But when there are lots of data in the array(maybe 100 or more),the images will be showed in disorder.For example, the image should be in the third "li" will be showed in the fourth "li".Could anyone tell me why,please!
PS. I use the ionic.bundle.js,but I dont know it will cause something wrong or not. And when the event of ion-infinite-scroll be tiggered,I will push the new data into the "comments" array.
Tracking by $index is not a good idea. Can you track by commentItem.id (or another unique identifier on the commentItem) instead? I'm not sure if that will solve the problem but looking at that code snippet, that's the first thing I would try.

Static list item inside ngRepeat

So,
I am rendering a basic list using ngRepeat, but need the first <li> to be static content, rather than being generated from the data array:
e.g.
<ul ng-repeat="item in items">
<li>This is text from the template and will always be the same.</li>
<li>{{item}}</li>
</ul>
I've also looked at using ng-repeat-start, but just can't quite get to a solution.
It is a common misconception that people want to use ng-repeat on the parent element, when in fact you use it on the actual elements that do the repeating.
You just need to change it to:
<ul>
<li>This is text from the template and will always be the same.</li>
<li ng-repeat="item in items">{{item}}</li>
</ul>

correct strategy to generate html dynamically with angular

I have a huge JSON object tree with two levels. First level has around 500 elements, and each element contains an average of 100 child elements.
I want to display the first level of the tree and I am doing it with a simple ng-repeat. When the user clicks on the element I want to display the child elements of that element. If I use a span ng-switch or a ng-show to show/hide child elements when the page first renders it freezes for around 10 seconds while generating all the HTML.
It doesn't sound like the right solution. There must be a different way of doing it, but I can't figure out. Anyone knows?
I have explained most in my comment, and here is a working plunker:
http://plunker.co/edit/RSZwfLlsCJ68MUkACbdp?p=preview
the new ng-if directive will do what you want
<h1>ng-if</h1> <h5>Click on the level to expand</h5>
<div class="well">
<ul class="nav nav-list" ng-repeat="(attr,element) in tree">
<li ng-click="expand=!expand" ng-class="{'active':expand}"><a>{{element.name}}</a></li>
<ul ng-if="expand" class="nav nav-list">
<li ng-repeat="item in element.items">{{item.name}}</li>
</ul>
</ul>
</div>
you can also do this in the "old-way" with ng-show using new ternary operator or its alternative expr && if_true || if_false
<h1>old-way</h1> <h5>Click on the level to expand</h5>
<small>use ternary operator or <pre>expand && element.items || []</pre></small>
<div class="well">
<ul class="nav nav-list" ng-repeat="(attr,element) in tree">
<li ng-click="expand=!expand" ng-class="{'active':expand}"><a>{{element.name}}</a></li>
<ul ng-show="expand" class="nav nav-list">
<li ng-repeat="item in (expand ? element.items : [])">{{item.name}}</li>
<!--<li ng-repeat="item in (expand && element.items || [])">{{item.name}}</li>-->
</ul>
</ul>
</div>
See this answer on ng-repeat performance. Essentially, it just takes a long time since Angular's ng-repeat, and basically all other directives, are set up to always look for updates in the whole JSON structure. So if you have lots of data and don't need live updates in the HTML view when changing the JSON, I wouldn't recommend using AngularJS. Generally, AngularJS performance also depends a lot on the browser and its JavaScript engine.
Alternatively, you could divide your JSON into subparts and then use pagination to display it.
I would recommend to fetch the data gradually from the server. Use server-side pagination and retrieve only the fields that you are going to display. Then, when a user clicks on one of the first level items, you can do another XHR to the server with the new data. I had similar requirements for a project and that solved the latency issue.
Regards,
Agustin.

Resources