Paflow
Paflow

Reputation: 2377

Observable of Array to Array of Observables with ngFor

In my Angular (9) App I get from WebsocketService an Observable of an Array of Objects like so:

public objects$: Observable<MyClass[]>;

ngOnInit(): void {

  this.objects$ = myWebsocketService.get()

Then I iterate over this with *ngIfand for every object call a component to render it:

<table>
  <tr *ngFor="let element of objects$ | async">
    <td><my-component [item]="element"></my-component><td>

That works. But that would mean, everytime objects$ changes every instance of my-component has to be reloaded. That seems very inefficient to me! Would be far better to a) only re-init the ones which actually changed and b) not even then re-init the my-components, but keep them, handle them observable out and subscribe to it. But I don't know how to formulate such behavior, in combination with the *ngFor - Any help is appreciated!

Upvotes: 1

Views: 480

Answers (2)

G&#233;r&#244;me Grignon
G&#233;r&#244;me Grignon

Reputation: 4238

You can use trackBy on *ngFor to deal with changes. It allows you to check each element and rerenders only the ones that are new. You can use an id or another unique elements to check them.

Template :

<tr *ngFor="let element of objects$ | async; trackBy: trackByFunction">
</tr

Component :

trackByFunction(index: number; element: MyClass) {
 return element.id; // or another unique property
}

Here is an example i made few days ago on Stackblitz (with a message on new elements to tag them)

Upvotes: 3

Sergio
Sergio

Reputation: 819

It is an observable element. So you could subscribe to that object and Angular do check for changes and will update your variable without reloads.

Something like this:

this.yourWebSocketService.yourObservableObject.subscribe( data=> {
    this.objects$ = data
}

Upvotes: 0

Related Questions