Reputation: 725
Here I have query that how can I call a interval method in the subscribe and stop it after the condition is met
below is my code
Main Subscribe method
this.authservice.getdata().subscribe(response => {
console.log(res)
// Polling method
SetInterval(()=>{
this.getInterval();
},5000)
})
Interval Method:
getInterval(){
this.authservice.getIntervalData().subscribe(resp => {
console.log(resp)
this.responseStatus = resp
})
}
In the response it gives 3 types of response
Proceed
Stop
Terminate
So here I need to call that getInterval() in Main subscribe method and until GetInterval gives me Proceed as response or until 1 min from polling I have set the interval running if either of this conditions are met i have to stop polling.
Note: I dont need polling for Main Subscribe method if main subscribe give response on success then only I have starte this polling
Update: The below Method works but here i need 2 things
How can set variables and store the response in that
How can i set the boolean variable based on res like if the response comes
this.content =true like wise
because when i am trying to set the variables in switchMap it is not accepting
this.authservice.getdata().pipe( switchMap(resp => timer(0, 5000).pipe( // need to store this response in global variable so that it can be used for further switchMap(t => this.authservice.getIntervalData( <1st response param> ).pipe( map(data => [data, t]))) takeWhile(([data, t]) => data !== 'TERMINATE' && t < 12), map(([data, t]) => data) )) ).subscribe(data => console.log(data))
Upvotes: 2
Views: 2735
Reputation: 6432
Consider implementing it as demonstrated below:
this.authservice.getdata().pipe(
tap(x => this.globalVariable = x),
switchMap(data => interval(5000).pipe(
switchMap(x => this.authservice.getIntervalData(x)), //<== pass data from first subscription to second
takeUntil(timer(60 * 1000)),
takeWhile(x => x !== 'TERMINATE'),
map(data2 => [data, data2]) // <= return values from both subscriptions
))
Update:
"stop this interval outside of method i mean like a button click"
clicked$ = new Subject<void>();
onclick(){
this.clicked.next(); // on click emit value
}
this.authservice.getdata().pipe(
tap(x => this.globalVariable = x),
switchMap(data => interval(5000).pipe(
switchMap(x => this.authservice.getIntervalData(x)), //<== pass data from first subscription to second
takeUntil(timer(60 * 1000)),
takeWhile(x => x !== 'TERMINATE'),
map(intervalDataRes => this.condition = intervalDataRes),
takeUntil(merge(this.clicked$, timer(2 * 60 * 1000))) // interval will stop after 2 or as soon as clicked$ emits
))
Upvotes: 0
Reputation: 29345
you probably want to just use operators and observables....
this.authservice.getdata().pipe( // get initial data
tap(resp => this.myVariable = resp),
switchMap(resp => timer(0, 5000).pipe( // switch to timer that emits every 5 seconds
switchMap(t => this.authservice.getIntervalData().pipe( // swtich again to interval data
map(data => [data, t]))) // map to response and timer value
takeWhile(([data, t]) => data !== 'TERMINATE' && t < 12), // whatever stop condition, this says stop when the data is terminate or the timer has emitted 12 times (1 minute if emitting every 5 seconds)
map(([data, t]) => data) // just send the data through
))
).subscribe(data => console.log(data))
something like that is how I would implement this.
Upvotes: 5
Reputation: 15083
Consider using Subject
to store the global variable. This way you will avoid subscribing altogether
Below Solution is tested on stackblitz, see this link
// Emit Once after 60 Seconds
stopTime$ = timer(60000);
// TerminateResponse
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
// Emits Every 5 seconds until stopTime is called
interval$ = timer(0, 5000).pipe(
takeUntil(this.stopTime$),
takeUntil(this.terminateAction$),
);
// Global Variable
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
// Create Interval Observable. This will call getIntervalData until no more interval
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),
tap(res => this.responseSubject$.next({res, content: true})),
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): ''),
)
We define a variable
stopTime$ = timer(60000);
This emits once after 60000ms ie 1Min
Next we define
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
We will use this observable to terminate the timer when condition is met using takeUntil
operator and calling the next()
function on the observable
We then define
interval$ = timer(0, 5000).pipe(
takeUntil(this.stopTime$),
takeUntil(this.terminateAction$),
);
this observable will emit with 0 delay every 5000ms until either stopTime$
observable is called or terminateAction$
is called
We then create a subject to store our global variables. Since observables are asynchronous, to avoid values being undefined, it would make sense to use observables to store our variables and subscribe to this variables whenever we need them
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
Finally we define our interval Data Observable
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),
tap(res => this.responseSubject$.next({res, content: true})),
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): ''),
)
tap(res => this.responseSubject$.next({res, content: true}))
stores the global variable
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): '')
Terminates the interval observable
Upvotes: -1