2

I would like to save some Angular 2 component related data to the database just before navigating from that particular component to another component so that database saved data will be able to display on the second component. In order to do that I called the save method on ngOnDestroy() hook of the first component and display method on second component ngOnInit().

However, It looks like ngOninit() calls before ngOnDestroy() completely finished. It means before saving data into the database second component retrieve old data and displaying.

Please help me to resolve this issue.

chenk
  • 392
  • 7
  • 27
  • Would it be possible if you push the data in the first component into a shared service between the two components and subscribe to it in your second component's init? – eko May 09 '16 at 09:52
  • In my case, only a particular saved item is indirectly required for displaying some processed data in the second component. So having a shared service is not much fit in this scenario. Would it be any other way of synchronize loading the components? – chenk May 09 '16 at 09:57

2 Answers2

2

If you are in the context of routing and you rely on the (old) router, you could leverage the OnActivate and OnDeactivate interfaces rather. Both contain methods that supports promises.

For the routerOnDeactivate one, if a promise is returned, the route change will wait until the promise settles.

Dan
  • 5,836
  • 22
  • 86
  • 140
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
2

You can implement CanDeactivate for this purpose. The router only continues the route change if a Promise returnes from routerCanDeactivate resolves to true

See also https://angular.io/docs/ts/latest/api/#!?apiFilter=candeactivate

rc.x

routerCanDeactivate(currTree?: RouteTree, futureTree?: RouteTree) : Promise<boolean> {
  return new Promise<boolean>((resolve, reject) => {
     ...
  })
}

beta.x or router-deprecated in rc.x

routerCanDeactivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction)  {
  return new Promise<boolean>((resolve, reject) => {
     ...
  })
}

The router-deprecated also has OnDeactivate. https://angular.io/docs/ts/latest/api/router-deprecated/index/OnDeactivate-interface.html. This might be added to the new router as well.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks. I would prefer to use 'rxjs/Observable' to return instead of direct Promise. – chenk May 09 '16 at 12:11
  • 2
    Angular only supports `Promise` or just `boolean` as return type but you can call `toPromise()` on your observable to get a promise that resolves when the observable is completed. Don't forget to import the `toPromise` operator. – Günter Zöchbauer May 09 '16 at 12:32