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)