1

I am requesting a SaaS api due to a 3rd party library. Server finishes rendering angular universal app when there are outstanding/unfinished service calls.


I am using Angular 5.2.0 and it's SSR functionality. This is an abstract structure of my setup:

server.ts

/* ... */
renderModuleFactory(AppServerModuleNgFactory, {
  document: template,
  url: options.req.url,
  extraProviders: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}).then(html => {
  console.log('--- HTML DATA FETCHED ---');
});
/* ... */

my.component.html

<div *ngIf="data$ | async as responseData">
  Data is available
</div>

my.component.ts

export class MyComponent implements OnInit {
  public data$: Observable<any>;
  @Input() serviceKey: string;

  constructor(private serviceWrapper: ServiceWrapper) { }

  ngOnInit() {
    this.data$ = this.serviceWrapper.get(this.serviceKey);
  }
}

service-wrapper.service.ts

export class ServiceWrapper {
  private thirdPartyClient: ThirdPartyClient;
  constructor(private _zone: NgZone) {
    /* ...initialize thirdPartyClient... */
  }
  get(serviceKey: string): Observable<any> {

    console.log(serviceKey + ' is stable: ' + this._zone.isStable);
    console.log(serviceKey + ' outstanding macrotasks: ' + this._zone.hasPendingMacrotasks);
    console.log(serviceKey + ' outstanding microtasks: ' + this._zone.hasPendingMicrotasks);

    return new Observable<any>(subscriber => {
      this.thirdPartyClient.getFromRemote(serviceKey).then(response => {
        subscriber.next(response);
        subscriber.complete();
      });
    });
  }
}

app.component.html

<app-my-component service-key="keyA"> </app-my-component>
<app-my-component service-key="keyB"> </app-my-component>
<app-my-component service-key="keyC"> </app-my-component>
<app-my-component service-key="keyD"> </app-my-component>
<app-my-component service-key="keyE"> </app-my-component>

Output

keyA is stable: false
keyA outstanding macrotasks: false
keyA outstanding microtasks: false
keyB is stable: false
keyB outstanding macrotasks: true
keyB outstanding microtasks: true
keyC is stable: false
keyC outstanding macrotasks: true
keyC outstanding microtasks: true
keyD is stable: false
keyD outstanding macrotasks: true
keyD outstanding microtasks: true
--- HTML DATA FETCHED ---
keyE is stable: false
keyE outstanding macrotasks: false
keyE outstanding microtasks: true

user9141607
  • 35
  • 1
  • 8
Sepanyol
  • 90
  • 7
  • This is because Zones is not wrapped around (and aware) of these Http calls as they're outside of Angular. You're going to have to make your own custom provider that fires the calls for you, and make it Zone aware. Some info on that here https://github.com/angular/angular/issues/15278#issuecomment-326034463 – Mark Pieszak - Trilon.io Jan 24 '18 at 19:38
  • 2
    i've solved this issue today with scheduling a zone macro task in my service – Sepanyol Jan 24 '18 at 19:42
  • @dcballs Hi. May I ask, how did you do the `zone macro task` part of the process? I'm doing something similar with a 3rd party API call - as the server is not waiting for the response. – Drenai Jul 30 '18 at 08:26
  • @Drenai did you already take a look here? https://github.com/angular/angular/blob/master/packages/platform-server/src/http.ts#L38 in my case i've switched from delegate to a fromPromise – Sepanyol Aug 12 '18 at 19:52

0 Answers0