Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example

What is polling, and when does it come into play?

Polling is like checking your mailbox every few minutes, hoping for that important letter. In programming, it refers to repeatedly sending requests to the server at regular intervals to check…


This content originally appeared on DEV Community and was authored by Yevheniia

What is polling, and when does it come into play?

Polling is like checking your mailbox every few minutes, hoping for that important letter. In programming, it refers to repeatedly sending requests to the server at regular intervals to check if new data is available.

Real-world scenario:
Imagine a web app - an internet-shop with both frontend and backend parts. After selecting items, a customer proceeds to the cart and clicks the 'buy' button. When this happens, the frontend sends a /buy HTTP request to the backend. The backend then performs several operations to complete the purchase:

  1. Creating a new order entry.
  2. Updating the database for the selected items.
  3. Handling third-party communications for payment processing.

These actions can take anywhere from a few seconds to a few minutes. To avoid keeping the client waiting for so long, the backend often responds immediately with a 202 Accepted status and a taskId, while continuing to process the request in the background. The frontend's role here is to poll the server at regular intervals using the taskId to check when the data is ready.

In this article, I’ll show you a simple and effective way to implement polling into an Angular frontend app:

**cart.component.ts**

import { Component, OnInit } from '@angular/core';

import { take } from 'rxjs';

import { HttpService } from '../../modules/shared/services/http.service';
import { AuthService } from '../../modules/shared/services/auth.service';

@Component({
    selector: 'app-cart',
    templateUrl: './cart.component.html',
    styleUrl: './cart.component.scss',
})
export class CartComponent implements OnInit {
    constructor(
        private readonly httpService: HttpService,
        private readonly authService: AuthService,
    ) {}

    ngOnInit() {}

    private executePurchase(selectedGoodsIds: Array<string>): void {
        const params = {
            userId: this.authService.currentUserId,
            goods: [...selectedGoodsIds],
        };
        this.httpService
            .executePurchase(params)
            .pipe(take(1))
            .subscribe({
                next: res => {
                    console.log(res); //here your logic
                },
                error: err => console.error(err),
            });
    }
}

**http.service.ts**

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

import { Observable, catchError, delay, filter, map, of, startWith, switchMap, timer } from 'rxjs';

import { AppConfig } from '../../../configs/app.config';
import { IResponse } from '../interfaces/response.interface';
import { ParsePurchaseService } from './parse-purchase.service';
import { IPurchase, IExecutePurchaseResponse } from '../interfaces/purchase.interface';

@Injectable({
    providedIn: 'root',
})
export class HttpService {
    constructor(
        private readonly http: HttpClient,
        private readonly parsePurchaseService: ParsePurchaseService,
    ) {}

    public executePurchase(params: IPurchase): Observable<IExecutePurchaseResponse> {
        return this.executePurchaseRequest(params);
    }

    public pollData(url: string, interval: number): Observable<any> {
        return timer(0, interval).pipe(
            startWith(null), // Start with null to avoid immediate emission at the beginning
            delay(interval),
            switchMap(() => this.http.get<any>(url)),
            catchError(error => {
                throw new Error(`Polling error: ${error}`);
            }),
        );
    }

    private executePurchaseRequest(params: IPurchase): Observable<IExecutePurchaseResponse> {
        return this.http.post<IResponse>(`${AppConfig.API_URL}/purchase/execute`, params).pipe(
            switchMap(data => {
                if (data.status === 200) {
                    return of(data).pipe(
                        map(parsedData => this.parsePurchasesService.parseCommitedPurchaseResponse(parsedData.data)),
                    );
                } else if (data.status === 202 && data.data.taskId) {
                    return this.pollData(
                        `${AppConfig.API_URL}/purchase/execution-status/${data.data.taskId}`, //every 5 seconds poll server
                        5000,
                    ).pipe(
                        filter(res => res?.data?.status === 'done'),
                        map(parsedData => this.parsePurchasesService.parseCommitedPurchaseResponse(parsedData.data)),
                    );
                } else {
                    return of(data).pipe(
                        map(parsedData => this.parsePurchasesService.parseCommitedPurchaseResponse(parsedData.data)),
                    );
                }
            }),
            catchError(error => {
                throw error;
            }),
        );
    }
}

Thanks for reading, hope it was useful, please feel free to comment))


This content originally appeared on DEV Community and was authored by Yevheniia


Print Share Comment Cite Upload Translate Updates
APA

Yevheniia | Sciencx (2024-09-14T17:09:10+00:00) Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example. Retrieved from https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/

MLA
" » Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example." Yevheniia | Sciencx - Saturday September 14, 2024, https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/
HARVARD
Yevheniia | Sciencx Saturday September 14, 2024 » Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example., viewed ,<https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/>
VANCOUVER
Yevheniia | Sciencx - » Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/
CHICAGO
" » Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example." Yevheniia | Sciencx - Accessed . https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/
IEEE
" » Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example." Yevheniia | Sciencx [Online]. Available: https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/. [Accessed: ]
rf:citation
» Data Polling on the Frontend for Long-Running HTTP Requests: Angular Example | Yevheniia | Sciencx | https://www.scien.cx/2024/09/14/data-polling-on-the-frontend-for-long-running-http-requests-angular-example/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.