Using Long Polling with Angular 4

I am looking for a way to monitor the progress of a certain task using API calls.

To achieve this, I have developed a service that executes these API calls every 1.5 seconds

Main Component

private getProgress() {
        this.progressService.getExportProgress(this.type, this.details.RequestID);
    }

Services.ts

public getExportProgress(type: string, requestId: string) {
    Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {
            if (!data.InProgress)
                // Stop further API calls here
        },
        error => this.handleError(error));
}

Although the API call is functioning properly, it continues even after the progress is complete (if (!data.InProgress). I need help in figuring out how to unsubscribe from the observable when this condition is met.

Any suggestions on how I can implement an unsubscribe feature based on if (!data.InProgress)?

Appreciate any guidance

Answer №1

One possible solution is to utilize the takeWhile operator.

For more information, refer to the official documentation: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-takeWhile

The main functionality of this operator is to emit values from the source Observable only when they satisfy a certain condition specified by the predicate function. It then completes as soon as one value does not meet this condition anymore.

Here's a basic example scenario showcasing how it can be used:

Rx.Observable
  .interval(100)
  .takeWhile(x => x < 10)
  .subscribe(x => { console.log(x); });

Below is an example implementation using your code:

public getExportProgress(type: string, requestId: string) {
    Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .takeWhile((data) => data.InProgress)
        .subscribe(
        (data) => {
            ...
        },
        error => this.handleError(error));
}

Answer №2

I found a solution by storing the service call in a variable and unsubscribing from it when finished.

Below is the updated code snippet:

public getExportProgress(type: string, requestId: string): any {
    let progress = Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {              
            if (!data.InProgress) {
                this.toastyCommunicationService.addSuccesResponseToast("done");
                progress.unsubscribe();
            }            
        },
        error => this.handleError(error));
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Prepare fixtures for commands in Cypress before executing the hook

One of my main tasks is to load the fixtures file only once and ensure it is accessible across all project files. To achieve this, I created a fixtures.js file with the following content: let fixturesData; export const loadFixturesData = () => { cy ...

Issue with Angular 4: Radio button defaults not being set

After hardcoding the value in component.ts, I am able to see the pre-selected radio button. However, when attempting to retrieve the value from sessionStorage, it does not work as expected. The value is visible in the console though. Could someone please ...

Issue encountered with Vue.js build configuration not being loaded while running on the build test server

I am working on a Vue 2 project and facing an issue with loading configuration settings from a config.json file. My router\index.ts file has the line: Vue.prototype.$config = require('/public/config.json') The config.json file contains imp ...

When attempting to access http://localhost:3000/traceur in Angular 2 with the angular-in-memory-web-api, a 404 (Not Found) error

Hello, I'm encountering an issue with angular-in-memory-web-api. I have attempted to use angular2-in-memory-web-api in SystemJS and other solutions, but without success. I am currently using the official quickstart template. Thank you for any assistan ...

Identifying the origin of the error (whether it's from the client or the server) within

I am utilizing ngrx effect for handling user login in my application: @Effect() authLogin = this.actions$.pipe( ofType(LOGIN_START), switchMap(() => this.http.post('/user/login') .pipe( catchError( (response) => ...

Search input in real-time

I am in the process of implementing a live search input feature in Ionic 3 within a form group. Within my TypeScript file, I have the following code: getSubElements(selectedValue) { if(selectedValue){ this.VisitesProvider.getEcolesLi ...

Working with arrow functions in TypeScript syntax

I came across the following code snippet in TypeScript: (() => { const abc = 'blabla'; ... })(); Can someone explain what exactly this syntax means? I understand arrow functions in JS, so I get this: () => { const abc = &apos ...

When additional lines are drawn elsewhere on the HTML5 Canvas, the diagonal lines will gradually appear thicker and more pronounced

For horizontal and vertical lines, using a translation of 0.5 for odd stroke widths results in crisper and sharper lines. But what about diagonal lines? Link to jsfiddle <!DOCTYPE html> <html lang="en"> <body style="background: black"& ...

Iterating through a for loop in Angular2 to send multiple GET requests to a Django backend

Currently, I'm facing a challenge with performing multiple GET requests using Angular2 within a Django/Python environment. After successfully making an API request and retrieving a list of users to determine the current user's ID, I utilize a .f ...

Switching from HttpModule to HttpClientModule

Angular's transition from HttpModule to HttpClientModule is causing some confusion, as discussed in detail here. The official Angular tutorial at https://angular.io/tutorial/toh-pt6 still uses HttpModule, while the Fundamentals documentation at https ...

Establish a table containing rows derived from an object

I am currently dealing with a challenge in creating a table that contains an array of nested objects. The array I have follows this schema: array = [ { id: 'Column1', rows: { row1: 'A', row2 ...

What is the best way to implement an asynchronous function using a for loop and APIs in Typescript?

Struggling with ensuring my function returns data only after completing all API calls and the for loop. getListingsImages(sessionID, mlsSearchCriteria){ this.http.get(this.laconiaBaseURL + "mls/search/" + sessionID + "?" +querySt ...

Error: The program encountered a type error while trying to access the '0' property of an undefined or null reference

I am a beginner in the world of coding and I am currently working on creating an application that allows users to add items to their order. My goal is to have the quantity of an item increase when it is selected multiple times, rather than listing the same ...

Specifying the data structure of a complex nested Map in TypeScript

Struggling to create a deeply nested (recursive) Map in Typescript generically. My attempt is to convert the provided Javascript example to Typescript: const map1 = new Map([ ['key1', 'value1'] ]) const map2 = new Map([ ['keyA& ...

Angular project service file experiencing issues with TypeScript string interpolation functionality

Here is the code snippet for a service in an Angular project: @Injectable() export class FetchDataService { fetch(link){ console.log('This is a ${link}'); } } In my component, I am invoking this method with a string parameter. Upon che ...

Utilizing getServerSideProps and getInitialProps in Next.js to optimize page loading times

My page is not loading when I use getServerSideProps or getInitialProps. It keeps on loading without displaying the content, but everything works fine when I remove them. What could be wrong with my code here? HELP. ... interface Props { data: any; } co ...

PhantomJS version 2.1.1 encountered an error on a Windows 7 system, displaying "ReferenceError: Map variable not found."

I've been utilizing the "MVC ASP.NET Core with Angular" template. I'm attempting to incorporate phantomJS and execute the tests, but encountering the following errors: ERROR in [at-loader] ..\\node_modules\zone.js\dist&bs ...

Troubles encountered while attempting to properly mock a module in Jest

I've been experimenting with mocking a module, specifically S3 from aws-sdk. The approach that seemed to work for me was as follows: jest.mock('aws-sdk', () => { return { S3: () => ({ putObject: jest.fn() }) }; }); ...

Guide on Implementing Link href in Next.js v12

When I set the href as a string, the link functions properly. However, when I use an object for the href, the link fails to work. Despite seeing the correct querystring when hovering over the link, it always takes me back to the first page. // ProdCard t ...

The TypeScript compiler encounters difficulties in locating type definitions when utilizing an inherited tsconfig file

There seems to be an issue with the functionality of tsconfig.json inheritance, specifically regarding the proper inheritance of the "typeRoots" setting. http://www.typescriptlang.org/docs/handbook/tsconfig-json.html (folder structure provided below) we ...