Home > database >  When using subscribe inside a while loop, it should wait till subscribe code is complete before next
When using subscribe inside a while loop, it should wait till subscribe code is complete before next

Time:02-03

I am currently subscribing to an observable inside a while loop. The condition for while loop is a flag, whose value is updated based on some values from the current response. However the while loop doesn't wait for the flag to be updated (or code inside subscribe to be executed completely), and hence the loop runs infinitely.

The requirement is to continuously make new POST request as long it return a response object which has a field "continue" as "true" and each request should be made using the updated values for varA and varB from current response.

For e.g. if after 4 subscribe and corresponding responses, if 5th response has {continue: "false"} then the loop should terminate immediately making total iterations

So basically the loop should terminate immediately when res['continue'] is not "true". However, in my case the loop is executing infinitely and the value for testLoop is NOT becoming false. The loop is NOT updating the value for varA and varB in each iteration as well. Basically the loop does not wait till subscribe code completes execution.

Method in component.ts file

let testLoop = true;
let varA = 100;
let varB = 0;
while(testLoop){
    this.someService.sampleFunc(varA, varB).subscribe((res:any)=>{
        //do something with res
        if(res['continue'] == 'true'){
            varA = res['A'];
            varB = res['B'];
        }
        else{
            testLoop = false;
        }
    })
}

Method in service.ts file

sampleFunc(varA: number, varB: number){
    return this.http.post(url,{
        varA: varA,
        varB: varB
    })
}

sample response from POST method

{
    count: 100,
    varA: 10,
    varB: 10,
    continue: "true"
}

I had gone through multiple threads suggesting different rxjs operators, but could not find a solution which suits the above mentioned use case.

CodePudding user response:

You can create a function to make the call and to handle the answer, if the condition to make a new request success it calls to itself again (recursively) if not, it ends.

keepAlive = () => {
  this.service.makePostRequest().subscribe(answer=>{
    if (!answer.condition) return
    this.keepAlive()
})

}

CodePudding user response:

  obs$ = this.sampleFunc(1,2)
  sampleFunc(a:number,b:number)
  {
    return this.sampleCall(a,b).pipe(
      tap((res) => {
        ..do something with "res"..
      }),
      switchMap((res:any) => {
        if (res.continue == 'true') return this.sampleFunc(res.a, res.b);
        return EMPTY;
      })
    );
  }
  sampleCall(a:number,b:number)
  {
      return this.http.post(url,{
        varA: varA,
        varB: varB
      })
  }

Then you simple subscribe to obs$, and don't forget unsubscribe!!

See stackblitz (in the stackblitz I use async pipe to subscribe/unsubscribe)

  • Related