snippettypescriptangularCritical
Angular2: How to load data before rendering the component?
Viewed 0 times
datahowloadcomponentangular2thebeforerendering
Problem
I am trying to load an event from my API before the component gets rendered. Currently I am using my API service which I call from the ngOnInit function of the component.
My
My
My API service
```
import "rxjs/Rx"
import {Http} from "angular2/http";
import {Injectable} from "angular2/core";
import {EventModel} from '../models/EventModel';
@Injectable()
export class ApiService {
constructor(private http: Http) { }
get = {
event: (eventId: string): Promise => {
return this.http.get("api/events/" + eventId).map(response => {
return response.json(); // Has a value
}).toPromise();
}
}
My
EventRegister component:import {Component, OnInit, ElementRef} from "angular2/core";
import {ApiService} from "../../services/api.service";
import {EventModel} from '../../models/EventModel';
import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams, RouterLink} from 'angular2/router';
import {FORM_PROVIDERS, FORM_DIRECTIVES, Control} from 'angular2/common';
@Component({
selector: "register",
templateUrl: "/events/register"
// provider array is added in parent component
})
export class EventRegister implements OnInit {
eventId: string;
ev: EventModel;
constructor(private _apiService: ApiService,
params: RouteParams) {
this.eventId = params.get('id');
}
fetchEvent(): void {
this._apiService.get.event(this.eventId).then(event => {
this.ev = event;
console.log(event); // Has a value
console.log(this.ev); // Has a value
});
}
ngOnInit() {
this.fetchEvent();
console.log(this.ev); // Has NO value
}
}My
EventRegister template
Hi this sentence is always visible, even if ev property is not loaded yet
I should be visible as soon the ev property is loaded. Currently I am never shown.
{{event.id }}
My API service
```
import "rxjs/Rx"
import {Http} from "angular2/http";
import {Injectable} from "angular2/core";
import {EventModel} from '../models/EventModel';
@Injectable()
export class ApiService {
constructor(private http: Http) { }
get = {
event: (eventId: string): Promise => {
return this.http.get("api/events/" + eventId).map(response => {
return response.json(); // Has a value
}).toPromise();
}
}
Solution
update
-
If you use the router you can use lifecycle hooks or resolvers to delay navigation until the data arrived.
https://angular.io/guide/router#milestone-5-route-guards
-
To load data before the initial rendering of the root component
original
When
Change
change
This actually won't buy you much for your use case.
My suggestion: Wrap your entire template in an
and in
-
If you use the router you can use lifecycle hooks or resolvers to delay navigation until the data arrived.
https://angular.io/guide/router#milestone-5-route-guards
-
To load data before the initial rendering of the root component
APP_INITIALIZER can be used How to pass parameters rendered from backend to angular2 bootstrap methodoriginal
When
console.log(this.ev) is executed after this.fetchEvent();, this doesn't mean the fetchEvent() call is done, this only means that it is scheduled. When console.log(this.ev) is executed, the call to the server is not even made and of course has not yet returned a value.Change
fetchEvent() to return a Promise fetchEvent(){
return this._apiService.get.event(this.eventId).then(event => {
this.ev = event;
console.log(event); // Has a value
console.log(this.ev); // Has a value
});
}
change
ngOnInit() to wait for the Promise to complete ngOnInit() {
this.fetchEvent().then(() =>
console.log(this.ev)); // Now has value;
}
This actually won't buy you much for your use case.
My suggestion: Wrap your entire template in an
(template content) and in
ngOnInit() isDataAvailable:boolean = false;
ngOnInit() {
this.fetchEvent().then(() =>
this.isDataAvailable = true); // Now has value;
}
Context
Stack Overflow Q#35655361, score: 158
Revisions (0)
No revisions yet.