Search code examples
angularrxjsrxjs5rxjs6

How to put custom gap between interval for polling in Rxjs angular?


I would like to implement gap / delay between every interval call, i have tried below but it seems not working.

  pollOnInterval(threshold = 4000): Observable<any> {
    let thresholdValue = threshold;
    const increaseBy = 2000;
    const maxCount = 10;
    return interval(thresholdValue).pipe(take(maxCount)).pipe(delay(increaseBy)).pipe(map(() => {
      thresholdValue = thresholdValue + increaseBy;
      console.log((new Date).toLocaleTimeString());
    }));
  }

output
2:34:21 PM
2:34:25 PM
2:34:29 PM
2:34:33 PM
2:34:37 PM
2:34:41 PM
2:34:45 PM
2:34:49 PM
2:34:53 PM
2:34:57 PM

Edit -1 I have tried debounce and debouceTime, It didn't work too, Stackbliz link: https://stackblitz.com/edit/angular-ivy-tinm4r?file=src%2Fapp%2Fapp.component.ts

Edit - 2 I need in below way
2:34:21 PM
2:34:27 PM
2:34:35 PM


Solution

    1. You could pipe all the operators in a single pipe(). Each operator doesn't require it's own pipe.

    2. As mentioned in my comment, once the interval() is triggered using the thresholdValue, the subsequent changes to the thresholdValue variable won't have any effect on the interval() function. It will continue to emit for each time interval denoted by the thresholdValue initally.

    3. At the moment the observable is emitting undefineds since nothing is returned from the map.

    4. You need to use concatMap and pipe the delay to each emission individually. If not, the delay would be piped to the interval as a whole as seen in the question.

    Try the following

    var { from, of, Observable, interval } = rxjs;
    var { tap, delay, take, map, concatMap } = rxjs.operators;
    
    var displayBox = document.getElementById('display');
    
    function pollOnInterval(threshold = 4000) {
      let increaseBy = 4000;     // delay for first emission from `interval`
      const maxCount = 10;
      return interval(4000).pipe(
        concatMap(value => of(value).pipe(
          tap(() => 
            displayBox.innerHTML += `
              Interval: ${new Date().toLocaleTimeString()}; 
              Delay: ${increaseBy/1000}s
              <br />
            `
          ),
          delay(increaseBy)
        )),
        tap(() => increaseBy += 2000),     // <-- adjust `increaseBy`
        take(maxCount),
        map(() => new Date().toLocaleTimeString())
      );
    }
    
    pollOnInterval().subscribe({
      next: value => displayBox.innerHTML += `Subscription: ${value}<br /><hr>`,
      error: null,
      complete: () => displayBox.innerHTML += 'Observable complete.'
    });
    <script src="https://unpkg.com/[email protected]/bundles/rxjs.umd.min.js"></script>
    
    <p id="display"></p>