miechooy
miechooy

Reputation: 3422

Observable<Array> Angular2

I have object array in my Angular2 application. I am using SignalR to fill array when new object arrives. Now the point is when new object arrived I had error

cannot read property of undefined

I rode that it might be error because its working async and in html I used to take object inside object.

So now the code look like:

<div *ngFor="let event of events">
        <div class="card overview">
            <div class="overview-content clearfix ">
                <span class="overview-title" pTooltip="{{event.name}}">{{(event | async)?.user?.name}} / {{(event | async)?.date | date:"HH:mm" }}</span>
                <span class="overview-badge "> <i class="material-icons ">{{getActivityIcon(event.activityId)}}</i>
            <button type="button" pButton (click)="selectEvent($event,event,op);" icon="fa-search"></button> 
            </span>

            </div>
        </div>
    </div>

And now the error is

NgFor only supports binding to Iterables such as Arrays.

My object array is in component and look as below:

events: Observable<Event[]>;

I understand the error but how can I make it work now?

Upvotes: 2

Views: 28477

Answers (2)

AVJT82
AVJT82

Reputation: 73337

Seems you are not sure about what's the difference between async pipe and subscribe, since you are using an odd mix in your template code. Either use the async pipe or "manually" subscribe. Async pipe does the subscription and unsubscription for you and should not be used together with subscribe.

Short simple examples, first usage of async pipe:

Service:

getEvents(): Observable<Event[]> {
  return this.http.get('url')
    .map(res => res.json())
}

In component, we assign that observable to our observable events$:

events$ = this.myService.getEvents();

In HTML we use async pipe that does the subscription for us:

<div *ngFor="let event of events$ | async">
  {{event.name}}
</div>

...Aaaand then the usage of subscribe:

The service method would be the same, the difference is in the component:

events: Event[] = [];

ngOnInit() {
  this.myService.getEvents()
    .subscribe(data => {
       this.events = data;
    });
}

HTML:

<div *ngFor="let event of events">
  {{event.name}}
</div>

Here I think you mixed async pipe with asynchronously retrieved data. So the async pipe is not used for asynchronously retrieved data, but to subscribe and unsubscribe to Observable.

Hope this helped and made some clarification :)

Upvotes: 16

shammelburg
shammelburg

Reputation: 7308

I think this is what you are looking for.

The AsyncPipe accepts a Promise or Observable as input and subscribes to the input automatically, eventually returning the emitted values.

Angular.io - AsyncPipe

Upvotes: 0

Related Questions