Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5 Universal wait for http request to return during server-side render

I have an Angular 5 app that is served using ngExpressEngine (Followed the Angular Universal starter project). My app has a component that makes a HTTP request to to get some data to be displayed. All works correctly but when I use fetch as google bot it returns the rendered page but none of the data. Is there any make the ngExpressEngine server to wait for HTTP requests before rendering the page back to the user?

like image 353
Steve Fitzsimons Avatar asked Jan 04 '18 23:01

Steve Fitzsimons


2 Answers

You can use APP_INITIALIZER in your provider to delay app initialization until fetching your api from your client app module like:

//app.module.ts
        providers: [{provide: APP_INITIALIZER, deps: [HttpClient], multi: true,
    useFactory: (http: HttpClient: Promise) => new Promise<Your Data Interface>((resolve, reject) => http.get("").pipe(map(data => {
     //do something with data
resolve(data)
    }), catchError(error => of(error).pipe(map(() => //do something if error)))))}]
like image 163
Tarek Elmadady Avatar answered Nov 16 '22 05:11

Tarek Elmadady


I don't know about Angular 5, but with the latest Angular release (7.2 at the time I write this), I can confirm that all the data loaded via a Resolve is properly rendered on server side, and also all the data loaded via ngOnInit hooks, even if it is asynchronous.

That works thanks to Zone.js, indeed, it tracks all of the asynchronous operations and emits an onMicrotaskEmpty event when the asynchronous task queue is empty to let Angular know that the page is ready for rendering. For reference: what is the use of Zone.js in Angular 2

like image 42
Guerric P Avatar answered Nov 16 '22 05:11

Guerric P