tholo
tholo

Reputation: 541

How to loop with *ngFor in array of objects?

I'm learning Angular2, so please forgive me if I'm asking a stupid question. I am receiving an arrays of objects and it looks like this:

obj.json

data: [
        {
           item: "banana"
        }
     ],
     [
        {
           item: "apple"
        }
     ],
     [
        {
           item: "lemon"
        }
     ]

In my component file I have managed to scope it in a scope:

this.fruits = data[0].item;

The issue is I only manage to scope the first item, or the second item and so on, by the index. How can I scope them all and then show them in a HTML file with *ngFor?

Upvotes: 12

Views: 85574

Answers (5)

Jeff Moretti
Jeff Moretti

Reputation: 693

I was stumped for a long while on a simple *ngFor loop, and I couldn't figure out why I kept getting a 'item_r2 is undefined' error due to my loop.

Turned out, I had the *ngFor loop nested in a bunch of HTML, in particular a <div ngbAccordion> and other stuff that hid item/was a collapsible element. And I kept get the error I mentioned above when the element displayed/expanded.

However, I did notice that it worked just fine once I took the *ngFor loop out of my <div ngbAccordion> element (ie and into the top of the HTML tree)

UPDATE:

Found a full fix to my problem above. I had a race condition - see *ngFor displaying data but throwing 'undefined' error

2ND UPDATE:

Even using the Elvis (ie ? ) operator didn't quite solve my problem. Instead, I created a new 'helper' component and placed that instead in my <div ngbAccordion> element

ie:


etc etc code

<div ngbAccordionBody>
    <app-here-is-my-new-component></app-here-is-my-new-component>
</div>

etc etc code

Upvotes: 0

Yoav Schniederman
Yoav Schniederman

Reputation: 5391

export class SomeClass {
    public name: String;
    constructor(_name: String){
       this.name= _name;
    }
}    

let fruits : Array<SomeClass>[new SomeClass("banana"),new SomeClass("apple"),new SomeClass("lemon")];


<li *ngFor="let fruit of fruits">
   <b> {{fruit.name}} </b>           
</li>

Upvotes: 1

Wep0n
Wep0n

Reputation: 402

I don't exactly see the problem. I'm using this as well.

I have an array of objects: private receipts:receipt[] where receipt is an object that contains some relevant data

export class receipt {
    public imageData;
    private accountNo;
    private tripNo;
    private ticketType;
    //..getters/setters and other variables
}

Now after filling the array I simply use it like this (nevermind the ion-slides, this does work for divs as well):

<ion-slide *ngFor="let entry of receipts; let i = index" id="{{'imgSlideContainer_'+i}}">
     <div>
        <img src="{{entry.getImageData()}}" id="{{'imgSlide_'+i}}" (click)="openImageUtil(entry, 'imgSlide_'+i)">
     ...
</ion-slide>

This behaves as expected. For form, you can also use {{entry.imageData}} if it's an accessible property (Yes, I tested this)

Similarily for nested Objects you should be able to simply {{entry.someSubObject.someSubSubObject}}

Hope this helps.

Upvotes: 1

Cobus Kruger
Cobus Kruger

Reputation: 8615

Your array isn't valid JavaScript. Assuming your data actually looks like this:

data: [
        {
           item: "banana"
        },
        {
           item: "apple"
        },
        {
           item: "lemon"
        }
     ]

Then you'll iterate through the data like this:

<li *ngFor="let fruit of data">
   <b> {{fruit.item}} </b>           
</li>

Upvotes: 20

kind user
kind user

Reputation: 41913

Your object isn't valid. I've edited it.

To iterate over object properties, use:

<ul>
  <li *ngFor='let elem of data'>{{ elem.item }}</li>
</ul>

Working plunker

Upvotes: 4

Related Questions