问题
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