11

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?

Steve Fitzsimons
  • 3,754
  • 7
  • 27
  • 66
  • 1
    Came across this [A dockerized, headless Chrome rendering solution](https://github.com/GoogleChrome/rendertron) just now, scouting for an answer to another question. It looks a bit involved, but seems to target the problem you have. – Richard Matsen Jan 04 '18 at 23:39
  • When do you make the http request? – David Jan 05 '18 at 22:04
  • And can we see your server side code? – David Jan 05 '18 at 22:32
  • what do you mean `server side`? It's Angular Univeral. check my comment https://github.com/angular/universal-starter/issues/7#issuecomment-357679972 – Toolkit Jan 15 '18 at 13:18
  • By server side I mean render in the express server – Steve Fitzsimons Jan 15 '18 at 13:49
  • Did you find an answer? Because I'm stuck with this for about a month and no solution. – Black Mamba Oct 09 '18 at 16:32
  • Never actually went back to it to sort it but if I we're to try again i'd probably look at using a resolver (https://angular.io/api/router/Resolve). Probably not as nice a user experience as the page may hang while the data is loaded and then you see the navigation and data loads instantly – Steve Fitzsimons Oct 10 '18 at 13:11
  • Possible duplicate of [(Angular 6) Angular Universal - Not waiting on content API call](https://stackoverflow.com/questions/52270397/angular-6-angular-universal-not-waiting-on-content-api-call) – gorniv Jan 14 '19 at 10:25
  • How can this be a duplicate of something that was asked after it? It would be it that is the duplicate of this question. Anyway if you add all the polyfills in an angular 7 app it seems this all works now as expected – Steve Fitzsimons Jan 14 '19 at 10:28

2 Answers2

1

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

Guerric P
  • 30,447
  • 6
  • 48
  • 86
1

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)))))}]
Tarek Elmadady
  • 186
  • 2
  • 9