I am building a calendar-app that uses http.get to get information for a certain day from the backend (currently backend is a server-mock). My issue is that the asynchronous http.get is not fast enough to deliver the data during the page rendering and somehow the data does not get displayed once it arrived either, I believe change detection should pick this up normally. Regarding the http.get method I followed the example on Angular.io, found here https://angular.io/guide/http#subscribe
To the code:
FetchService:
getDayInfo(date: string): Observable<any> {
return this.http.get(url)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body; // not really doing much with the data here yet
}
component.ts:
dayData: any[];
dayInfo: any[];
constructor(private fetcher: FetchService) {}
ngOnInit(): void {
this.getDay();
setTimeout(() => { this.setDayData(); }, 10);
// the setTimeout is mostly here for testing, tried to sort of set the
// Data after the async http.get was done
}
getDay () {
this.fetcher.getDayInfo(this.date).subscribe(
body => this.dayInfo = body,
);
}
setDayData() {
if (this.dayInfo) {
this.dayData = this.dayInfo;
console.log(this.dayData);
// and some more things that only matter for some CSS markup
}
}
component.html:
<!--{{ dayInfo[0].type.name }}-->
<div *ngIf="dayData">
<div *ngFor="let data of dayData">
<p>{{ data.type.name }}</p>
</div>
</div>
<div *ngIf="!dayData">
<p>Loading</p>
</div>
Every day always just shows Loading, after the Timeout, the console fills with actual and proper dayData, site still only shows Loading. If I comment in the {{ dayInfo[0].type.name }} in the html, I first get a few days with "Loading" and a console with errors saying dayInfo is undefined, then bit by bit, the days fill, showing Loading and the data I want, though the console is full of errors as stated above.
Now, since I can't speed up the asynchronous http.get, is there a way to trigger the change detection to pick up the change in dayData? Or any other work-around for me to display the proper Data?
PS: another thing I noticed when console-logging the dayData in setDayData is that sometimes the log doesn't list all days, meaning it may show the first 27 days of a month, but have no log entry regarding the rest. Not sure what causes this.
Edit: After the first comment and first answer, I changed my getDay method in the component.ts to:
getDay () {
this.fetcher.getDayInfo(this.date).subscribe(
body => {
this.dayInfo = body;
this.setDayData();
);
}
Now the odd behavior I described in "PS:" above, is gone, all days are showing in the log, though they are mixed around (not in chronological order anymore). Site still only shows "Loading" though and does not update to the proper data. I would likely need to manually trigger change detection here or something.
Your timeout may be firing before you get your data. Instead of calling the setDayData from your ngOnInit, you probably want to call it from the body of your getDayInfo subscribe block.
This will make sure you have the data and your follow up methods are called after you receive the data.
ngOnInit(): void {
this.getDay();
}
getDay () {
this.fetcher.getDayInfo(this.date).subscribe(
body => {
this.dayInfo = body;
this.setDatData();
}
);
}
As for the other problem about getting undefined - that is because you have an empty array when the template is first displayed (it's not set until your setDayData method is run). You can wrap that in an ngIf too if you actually want that on screen. That way you know you have data there as well.
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