Jeremy P
Jeremy P

Reputation: 1407

Angular 2 - Chaining Web Service Calls

I am attempting to make a few web service calls in a row, but the problem I am having is that the second call will be made before the .subscribe ever executes on the first call. I need the .subscribe to happen in order to set this.saveValue, because this.saveValue is passed in the JSON of the second web service call.

What is happening currently with this code is that the first call will be made, then the second call will be made, and then the saveValue is set after that.

Component.ts

busy: Subscription;
saveValue: string;

submitButton_Click():void{
    try{
        // First Web Service Call
        this.busy = this.service.firstMethod(this.object)
            .first()
            .subscribe(result => {
                if(result.length > 0){
                    this.saveValue= result; // VALUE SET FOR USE OF NEXT WEB SERVICE CALL
                    console.log('Worked');
                }
                else{
                    console.log('Failed');
                }     
            })



        for(let current of this.array){
            let temp= new Object();
            temp.id = this.saveValue;

            // Second Web Service Call
            this.busy = this.service.secondMethod(temp)
                .first()
                .subscribe(result => {
                    if(result.valueOf() != false){
                        console.log('Worked');
                    }
                    else{
                        console.log('Failed');
                    }          
                })
         }

Service.ts

// First Method
public firstMethod(object: Object): Observable<string>{
    return this.client.post<Result>(URL + '/add', object, new Result(), this.token.id)
        .map(result => {
            let temp = new Object().deserialize(result.data);
            return temp.id;
        }, this)
        .catch(this.handleError);
}  // This works and returns proper value

// Second Method (Needs this.saveValue as part of the passed object)
public secondMethod(object: Object): Observable<boolean> {
    return this.client.post<Result>(OTHERURL + '/add', object, new Result(), this.token.id)
        .map(result => result.success, this)
        .catch(this.handleError);
}

Thanks for the help!

Upvotes: 1

Views: 943

Answers (2)

seidme
seidme

Reputation: 13058

Chaining the HTTP requests can be achieved using the Observable.flatMap operator. Say we want to make two requests where the second request depends on the result of the first one:

this.service.firstMethod(this.object)
    .flatMap(firstMethodResult => this.service.secondMethod(firstMethodResult))
    .subscribe(secondMethodResult => {
          console.log(secondMethodResult);
     });

This way you can chain as much interdependent requests you want.

If (for some reason) you want to use subscribe method only, then the second request needs to be made inside the subscribe callback of the first request:

this.service.firstMethod(this.object)
    .subscribe(firstMethodResult => {
        this.service.secondMethod(firstMethodResult))
            .subscribe(secondMethodResult => {
                console.log(secondMethodResult);
            });
    });

Hope it helped!

Upvotes: 1

zim
zim

Reputation: 2386

yes, because you have to wait for the first to finish. anytime you make an async call, execution will happily continue with the next bit of code. try it like this:

this.busy = this.service.firstMethod(this.object)
            .first()
            .subscribe(result => {
                if(result.length > 0){
                    this.saveValue= result; // VALUE SET FOR USE OF NEXT WEB SERVICE CALL
                    console.log('Worked');

            for(let current of this.array){
            let temp= new Object();
            temp.id = this.saveValue;

            // Second Web Service Call
            this.busy = this.service.secondMethod(temp)
                .first()
                .subscribe(result => {
                    if(result.valueOf() != false){
                        console.log('Worked');
                    }
                    else{
                        console.log('Failed');
                    }          
                })
         }
                }
                else{
                    console.log('Failed');
                }     
            })

sorry the formatting's rubbish; i don't have WebStorm handy and i'm lazy without it :-)

Upvotes: 1

Related Questions