Rxjs: Making recursive HTTP requests with a condition-based approach

To obtain a list of records, I use the following command to retrieve a set number of records. For example, in the code snippet below, it fetches 100 records by passing the pageIndex value and increasing it with each request to get the next 100 records:

this.employeeService.list(1, 100).toPromise().then(data => {
    this.employees = data.items;
});

If the data contains a flag named isComplete and its value is false, I would like to make another Http call to the same list method. What would be an appropriate way to achieve this using Rxjs in Angular? Some possible approaches include recursive subscriptions, but they may not be optimal for this scenario.

Answer №1

A Potential Solution:

To tackle this issue, consider using the expand and reduce methods:

If we assume that the page index begins at 0, the initial page index prior to 'expand' should be one less than the starting page index retrieved from your service.

of({
  isComplete: false,
  pageIndex: -1,
  items: []
}).pipe(
  expand(data => this.employeeService.list(data.pageIndex+1, 100).pipe(
    map(newData => ({...newData, pageIndex: data.pageIndex+1}))
  )),
  takeWhile(data => !(data.isComplete === true), true),
  map(data => data.items),
  reduce((acc, items) => ([...acc, ...items]))
).subscribe(res => {
  this.employees = res;
});

An Informative Note on Promises:

observableStream.toPromise().then(LAMBDA);

is essentially similar to

observableStream.pipe(last()).subscribe(LAMBDA);

last waits for the completion of the source and only emits the final value, disregarding all other values in the stream.

Individuals new to working with Observables and Promises often initially believe it functions more like:

observableStream.pipe(first()).subscribe(LAMBDA);

where it takes the first value and promptly resolves the Promise with that value. However, this assumption is incorrect.


In essence, opting to use either Observables or Promises exclusively is recommended. Observable encompasses Promises and, aside from specific scenarios necessitating promises, transitioning an Observable into a Promise should typically not be necessary.

Answer №2

customOperator is the key to your solution. Check out this example:

this.customService.performAction().pipe(
    customOperator((response) => {
        if(response.isSuccess) {
            return of(EMPTY);
        } else {
            return this.customService.performAction();
        }
    })
).subscribe((response) => {
    //add your custom logic here
});

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

The process of AJAX polling a JSON-returning URL using jQuery's $.ajax() method does not appear to provide up-to-date responses

I am currently working on a project that involves polling a specific URL for a JSON response using AJAX. The initial AJAX request alerts the server of my need for JSON content, prompting it to start building and caching the response. Subsequent AJAX reques ...

How to interact with AngularJS drop-down menus using Selenium in Python?

I have been working on scraping a website to create an account. Here is the specific URL: Upon visiting the site, you need to click on "Dont have an account yet?" and then click "Agree" on the following page. Subsequently, there are security questions th ...

Tips for eliminating unicode characters from Graphql error messages

In my resolver, I have implemented a try and catch block where the catch section is as follows: catch (err: any) { LOG.error("Failed to get location with ID: " + args.id); LOG.error(err); throw new Error(err); ...

Automatic Expansion Feature for HTML Tables

http://jsfiddle.net/bzL7p87k/ In my table, placeholders are filled with special words. However, what happens when I have more than 4 rows? For instance, if there are 21 placeholders for 21 rows? What I mean is this: I only have one row with a placeholder ...

Tips for establishing a universal onkeydown listener for all frames within a webpage?

Working with a complex legacy multi-frame webpage that needs to be compatible with IE-11 and responsive to hotkey events has brought up some challenges. It appears I can't simply declare a JavaScript method in the parent page. Rather, it seems that e ...

When clicking initially, the default input value in an Angular 2 form does not get set

I am currently learning angular2 as a beginner programmer. My goal is to create a form where, upon clicking on an employee, an editable form will appear with the employee's current data. However, I have encountered an issue where clicking on a user f ...

"Encountered a problem when trying to access file with node

An error has occurred: module.js:471 throw err; ^ Error: Module not found at '/Users/vinclo/app.js' at Function.Module._resolveFilename (module.js:469:15) at Function.Module._load (module.js:417:25) at Module.runMain (module.js:604:10) at run ( ...

What methods does Express use to precisely measure time intervals shorter than 1ms?

Recently, I started delving into the world of Express, a web framework for Node.js. While experimenting with it, I noticed that whenever a webpage rendered by Express was refreshed, a series of log messages appeared on my Linux console, as shown below: GE ...

Issue encountered while serializing the `.product` object retrieved from the `getStaticProps` function in NextJS, in conjunction with

I ran into an error message saying "Error: Error serializing .product returned from getStaticProps in "/products/[id]". Reason: undefined cannot be serialized as JSON. Please use null or omit this value." This issue occurred while I was attempting to crea ...

Webpack automatically prepends "auto/" to script tags in the compiled HTML file

I am currently setting up an application for coding, but I am facing a problem with webpack. Every time I build the application, webpack automatically adds "auto/file.js" to the script tags instead of just "file.js". I have checked all my webpack configura ...

Utilizing Regular Expressions to Substitute 'null' in API Data with a Custom String in JavaScript

I'm working with an API to gather information about books, including the title and author. However, I've noticed that some authors' data is returned as 'undefined'. I had the idea of using regular expressions (RegExp) to replace th ...

Having trouble installing dependencies in a React project with TypeScript due to conflicts

I encountered a TypeScript conflict issue whenever I tried to install any dependency in my project. Despite attempting various solutions such as updating dependencies, downgrading them, and re-installing by removing node_modules and package-lock.json, the ...

Sending simple form information through AJAX to a PHP web service

Attempting to send form data via jQuery and Ajax to a PHP web service (php file) for echoing the results. This is my index.html file <html> <head> <title>PHP web service &amp; AJAX</title> <link rel="stylesheet" type="text/ ...

Extracting web search result URLs using Puppeteer

I'm currently facing an issue with the code I've written for web scraping Google. Despite passing in a specific request, it is not returning the list of links as expected. I am unsure about what might be causing this problem. Could someone kindly ...

Ajax is updating the initial row of an HTML table while the subsequent rows remain unchanged and retain their default values upon modification

I need help with updating the status of a user, similar to what is discussed in this post. The issue I am facing is that only the first row of the table updates correctly. Regardless of the selected value from the dropdown list on other rows, the displaye ...

Tips for creating TypeScript Google Cloud Functions using webpack

I'm currently facing a challenge while coding a Google Cloud Function using TypeScript. The concept involves having handler functions defined for various Cloud Functions in separate files within the source repository, along with some code that is shar ...

Utilizing TypeScript with React to dynamically select which component to render

My task seemed simple at first: to render a React component based on its name/type. Here is an example of how it is used: // WidgetsContainer.ts // components have a difference in props shape! const componentsData = [ { type: 'WIDGET_1', ...

Vue: Issue with Firebase Authentication REST API triggers 400 Bad Request Error

Here is the error message I am encountering: POST scheme https host identitytoolkit.googleapis.com filename /v1/accounts:signUp key AIzaSyAk1ueCLjDDWCNrt_23o5A4RCfeaYIlN6k Address 74.125.24.95:443 Status 400 Bad Request VersionHTTP/3 Transferred850 B ...

The issue of the "port" attribute not working for remotePatterns in the Image component has been identified in Next.js 13's next.config.js

I've encountered an issue with the code snippet below. I'm attempting to utilize remotePatterns in my next.config.js file to enable external images. Strangely, when I set the port to an empty string "", it functions correctly. However, specifying ...

The sorting icon cannot be substituted with jQuery, AJAX, or PHP

Currently, I am working on implementing "sort tables" using ajax, jquery, and PHP. The sorting function is functioning correctly; however, I need to show/hide the "sorting images". At the moment, only one-sided (descending) sorting is operational because I ...