简体   繁体   中英

Angular2 - How to chain async service calls (http requests) in a component?

I have a component which first need to call a service that POST something. Then in the same component I want to wait until the POST is done, to call another service which GETs data.

How can I make the GET call wait for the POST call to finish?

In new-version.component.ts:

private createNewVersion(value) {
    ...

    // create new version, then call on all available versions

    // POST call
    this._newVersionService.createNewVersion(vnr);

    // GET call
    this._versionService.getAvailableVersions(); 

    ...
}

In new-version.service.ts:

export class NewVersionService {

response$: Subject<any>;

constructor(private _http: Http) {
    this.response$ = new BehaviorSubject<any>(null);
 }

public createNewVersion(versionNr) {    
    this._http.post('http://localhost:8080/services/' + versionNr, null, {
        method: 'POST',
    })
    .subscribe(response => {
        this.response$.next(response.status);
    },
    error => console.error(error));
}

Thanks!

When a call returns a Promise chain the calls with

someFunction() {
  return returnsPromise()
    .then(result => doSomethingNext())
    .then(result => doSomethingAfterThat());
}

Ensure you have a return that returns the Promise of that chain so the caller of someFunc() also has a chance to time additional work to execute after doSomethingAfterThat() is completed.

When a call returns an Observable then use the complete callback

someFunction() {
  return returnsObservable()
    .subscribe(
      event => doForEachEvent(),
      error => handleError(),
      () => doSomethingNext()
          .then(result => doSomethingAfterThat());
}

doSomethingNext() is executed after the last event and doSomethingAfterThat() is again chained with then() to show how to mix observable and promise. doSomething() .

You should be able to concat to achieve sequence, and reduce to collect the emitted values:

var a = this._newVersionService.createNewVersion(vnr);
var b = this._versionService.getAvailableVersions(); 

Rx.Observable.concat(a, b).reduce((acc:Array<any>, x:any) => {
    acc.push(x); return acc;
}, []).subscribe(t=> { 
      var firstEmitted = t[0];
      var secondEmitted = t[1];
});

You can do like this: Change createNewVersion to:

public createNewVersion(versionNr) {
 return this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
    method: 'POST',
 });
}

Then in your call:

this._newVersionService.createNewVersion(vnr).subscribe(response=> {
 this._versionService.getAvailableVersions(); 
}, error => console.error(error));

Another way to do the same is to subscribe in the new-version.component.ts and call you GET request from within the POST request ie check whether your POST request is done Correctly or not if yes POST is done Properly then call you GET request. As below:

In new-version.component.ts:

 private createNewVersion(value) {
    ...
    // create new version, then call on all available versions

    // POST call
    this._newVersionService.createNewVersion(vnr)
        .subscribe((res) => {
            if(res){
                console.log(res);
                if (---Post request done properly check via status or something else here----{
                    CALL YOUR GET REQUEST HERE.....
                    // GET call 
                    this._versionService.getAvailableVersions(); 
                }
                else {
                    DO something else whatever you want....
                }
            }
        });
    ...
}

In new-version.service.ts:

export class NewVersionService {

response$: Subject<any>;

constructor(private _http: Http) {
    this.response$ = new BehaviorSubject<any>(null);
 }

public createNewVersion(versionNr) {    
    this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
        method: 'POST',
    })
    .map(response => {
        return [{status: response.status, json: response.json()}];
    },
    error => console.error(error));
}

for more info related to http request you can read here .

Better use switchMap() here.

const versions$ = this._newVersionService.createNewVersion(vnr)
                 .switchMap(response => this._versionService.getAvailableVersions());

versions$.subscribe(response2 => this.versions = response2)

But the problem will be if you make another POST request before first has been resolved, the previous request will get cancelled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM