Angular 5 - Asynchronous Service Calls in two different components (First Method Not waiting for DB response)

↘锁芯ラ 提交于 2021-01-28 18:50:07

问题


I have to perform two different DB transactions on a single (click) event.

First Call : Save Data to DB.

Second Call : Get the first call's saved data from DB

These calls are separated in two different components and deal with one common DB Table.

My approach is below :

First Component TS :

ngOnDestroy(){ this.saveData(); }

Second Component TS :

ngOnInit(){ this.getSavedData(); }

Service call for First Method to Execute :

 saveData(obj) {
    return this.http.post(environment.appUrl + 'saveDataApi', obj).toPromise()
      .then(res => <any>res); }

Both these methods are getting triggered sequentially as coded. But my issue is that this.getSavedData(); completes its DB transaction earlier before Save method's DB transaction is completed & response is returned.

I need that the service call for 'Save' method should wait for DB response and then proceed to 'Get' method in other component.

In short : this.getSavedData(); should not be executed until and unless this.SaveData(); completes its entire execution returning a response.

What am I missing?


回答1:


Create a service called data.service.ts (name as you wish) to handle the HTTP call. Make a saveData method. Call that from the first component (although I'm not sure if ngOnDestroy is the best place to make a call like that):

ngOnDestroy(){ this.dataService.saveData(); }

Implement your service in a way that it emits the result from the service when the response suceeded:

@Injectable()
export class DataService {
  private _data$ = new ReplaySubject(1);
  public data$ = this._data$.asObservable();

  saveData(obj) {
    return this.http.post(environment.appUrl + 'saveDataApi', obj).pipe(
      tap(res => this._data$.next(res)
    )
      .toPromise()
      .then(res => <any>res); 
  }
}

In your second component, subscribe to the service's data$ Observable:

ngOnInit() {
  this.dataSubscription = this.dataService.data$.subscribe(() => [..])
}

And don't forget to unsubscribe when you leave the component:

ngOnDestroy() {
  this.dataSubscription.unsubscribe();
}

Or bind data$ to your template directly using the async pipe.
Maybe you should consider adding a state management framework to your application, like ngRX, but that is a bigger jump.



回答2:


If the component that is responsible for getting the data is a child component to the one that saves it, I would recommend pass data from parent to child with input binding.

Otherwise, you could create a shared service to notify sibling components.

See my answer here




回答3:


You may need to call onDestroy something like following code.

  async ngOnDestroy() {
    const res = await this.saveData(); 
  }


来源:https://stackoverflow.com/questions/55001261/angular-5-asynchronous-service-calls-in-two-different-components-first-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!