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!
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With