Angular long polling

html:

<section class="page-long-polling">
  <h1>Long polling</h1>

  <p>
    The request happen every <strong>{{ TIMEOUT_IN_SEC }}</strong> seconds or after click on the button.
  </p>

  <button
    class="btn btn-secondary"
    (click)="getNow()">
    Get random post now
  </button>

  <h4>Random post data:</h4>
  <pre>
    {{ postData | json }}
  </pre>
</section>

javascript:

import {Component, OnDestroy, OnInit} from '@angular/core';
import {HttpClient, HttpErrorResponse, HttpResponse} from '@angular/common/http';
import {merge, Subject, takeUntil, timer} from 'rxjs';
import {mergeMap} from 'rxjs/operators';

@Component({
  selector: 'app-long-polling',
  templateUrl: './long-polling.component.html',
  styleUrls: ['./long-polling.component.scss']
})
export class LongPollingComponent implements OnInit, OnDestroy {
  unsubscribe$ = new Subject<void>();
  TIMEOUT_IN_SEC = 5;
  userClickSubj = new Subject();
  postData = {};

  constructor(protected httpClient: HttpClient) {}

  ngOnInit(): void {
    // https://blog.strongbrew.io/rxjs-polling/
    merge(timer(0, this.TIMEOUT_IN_SEC * 1000), this.userClickSubj)
      .pipe(mergeMap((_) => this.getData()))
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe({
        next: (response: HttpResponse<any>) => {
          console.log('Response:', response);
          this.postData = response;
        },
        error: (error: HttpErrorResponse) => {
          console.log('Error:', error);
        },
        complete: () => {
          console.log('Complete');
        }
      });
  }

  getData() {
    const randomId = Math.floor(Math.random() * 100);
    return this.httpClient.get<any>(`https://jsonplaceholder.typicode.com/posts/${randomId}`);
  }

  getNow() {
    this.userClickSubj.next('');
  }

  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}

Leave a Comment