Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Async Data Issue

I have a component that is reliant upon an asynchronously fetched object. There are also child components in the template that rely on some data from this same object.

The problem I am having seems to be a classic race condition, but I'm not familiar enough with Angular 2 to understand the solution.

Take this for instance:

export class SampleComponent {
    constructor(service: SomeService) {
        this.service = service;
        this._loadData();
    }

    private _loadData() {
        this.service.getData().subscribe(data => this.data = data);
    }
}

But in the template, I have child components to display certain parts of this.data:

<taglist tags="data?.tags"></taglist>

Now the Component for taglist looks something like:

@Component({
    selector: 'taglist',
    directives: [NgFor],
    inputs: ['tags'],
    template: `<span *ngFor="#tag of tags">{{ tag }}</span>`
})

export class TagList {
    public tags: Array<string> = [];

    constructor() {
        //
    }
}

Because tags input is received from an async loaded dataset, its not present when the Tag Component is initialized. What can I do so that when this.data load is finished, the sub components that use it will automatically access the newly loaded data?

Thank you for any insight you may be able to provide me!

like image 432
Matthew Brown Avatar asked Feb 08 '16 16:02

Matthew Brown


People also ask

How to use async await in Angular function?

Basically, Async/Await works on top of Promise and allows you to write async code in a synchronous manner. It simplifies the code and makes the flow and logic more understandable. Note that because it no longer uses then and catch chaining anymore, you can handle errors by running try/catch.

What is the purpose of async pipe?

The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks.

What is asynchronous data in angular?

An asynchronous data stream is a stream of data where values are emitted, one after another, with a delay between them. The word asynchronous means that the data emitted can appear anywhere in time, after one second or even after two minutes, for example.

Does async pipe unsubscribe?

Every time a new value is emitted the async pipe will automatically mark your component to be checked for changes. And best of all, when the component is destroyed the async pipe will automatically unsubscribe for you.


1 Answers

Implement ngOnChanges() (https://angular.io/docs/ts/latest/api/core/OnChanges-interface.html)

@Component({
    selector: 'taglist',
    inputs: ['tags'],
    template: `<span *ngFor="let tag of tags">{{ tag }}</span>`
})

export class TagList {
    public tags: Array<string> = [];

    constructor() {
        //
    }

    ngOnChanges(changes: {[propName: string]: SimpleChange}) {
      console.log('ngOnChanges - tags = ' + changes['tags'].currentValue);
    }
}

For angular to handle the binding also use

<taglist [tags]="data?.tags"></taglist> or <taglist tags="{{data?.tags}}"></taglist>

otherwise it's a simple string to attribute assignment Angular doesn't handle.

like image 185
Günter Zöchbauer Avatar answered Sep 23 '22 19:09

Günter Zöchbauer