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

Is there a more efficient solution for incorporating undefined and null into a type apart from developing a custom generic function?

Often in programming, we encounter methods where one or more parameters can be null or undefined (sometimes both with derived types). This can result in long method signatures like this: doThing( user: User | undefined | null, thing: Thing | undefined ...

Guide on syncing Bootstrap 4 sliders using a single set of controls

Is it possible to synchronize a bootstrap 4 carousel with controls to a carousel without any controls? 1) When the control arrows are clicked, both carousels will slide simultaneously. 2) Hovering over either carousel will pause both carousels from slidi ...

Vue Pinia ensures that reactive state is only updated once, preventing unnecessary updates

In my Vue application, the structure is as follows: App.vue -GroupWrapper --GroupListing -PeopleWrapper --PeopleListing -ConversationWrapper Within my user store that utilizes Pinia, I primarily call user.findChats() in the App.vue component. Code snippe ...

What methods does MaterialUI utilize to achieve this?

Have you checked out the autocomplete feature in their component? You can find it here: https://mui.com/material-ui/react-autocomplete/ I noticed that after clicking on a suggestion in the dropdown, the input box retains its focus. How do they achieve thi ...

incorporate a new component in real-time

I need help with dynamically adding components to my container in AngularJS. I have a componentA that functions as a container, and I want to add multiple instances of componentB when a button is pressed. Currently, I can successfully add a single instanc ...

Ways to display only particular dates in react-dates

I am working with an array of dates. const availableDates = ["2019-02-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-11", "2019-02-12", "2019-02-13", "2019-02-14", "2019-02-15", "2019-02-19", "2019-02-20", "2019-02-21", "2019-02-22" ...

Issue with Angular 2 pipe causing unexpected undefined result

Here is a JSON format that I am working with: [{ "id": 9156, "slug": "chicken-seekh-wrap", "type": "dish", "title": "Chicken Seekh Wrap", "cuisine_type": [2140] }, { "id": 9150, "slug": "green-salad", "type": "dish", "title": "Green Sala ...

How to retrieve a Typescript variable within an ngIf conditional statement in Angular

How can I access a TypeScript variable inside an ngIf statement? TS: public data: string; HTML: <td> <div *ngIf="data === 'BALL' ; else noplay" >{{ play }}</div> <ng-template #noplay> {{ gotohome ...

What steps can be taken to prevent the "unable to convert undefined to an object" error from occurring?

There seems to be an issue with some of the documents not containing the planDetails and planId properties, resulting in the error "can't convert undefined to an object." However, I need to fetch that document whether these properties exist or not. Ho ...

Various JSON Tag values occurring more than once

Upon receiving a JSON Object in HTML, I am passing it to a JavaScript function defined below. The issue arises when the same folderName appears repeatedly on the HTML page. JSON Object: { "folderName": "arjunram-test", "objects": [ { ...

The process of transmitting messages back and forth between a popup script and a content script

I am in the process of developing a Chrome extension that involves sending data requests from a popup script to a content script (via a background script), analyzing the request on the content script, and then sending back a response (again through the bac ...

Struggling to pass along the URL value from a promise to various modules within Express is proving to be quite a challenge for me

I've been working on an app using ngrok, following a guide from Phil on setting up ngrok with nodemon. You can find the link to the post here. I need to have access to the URL received from the promise in the bin folder throughout the app server so t ...

Node React authentication

Struggling with implementing authentication in React Router. I am using componentDidMount to check if the user is logged in by calling an endpoint. If not, it should redirect to login, otherwise proceed to the desired component. However, this setup doesn&a ...

Encountered a problem with @types/ws while trying to upgrade from Angular 12 to Angular 13

After upgrading my project from Angular 12 to Angular 13, I encountered the following error: Error: node_modules/@types/ws/index.d.ts:328:18 - error TS2315: Type 'Server' is not generic. 328 server?: HTTPServer<V> | HTTPSServer< ...

Having difficulty retrieving information from Redux store

In my project, I utilize the Redux store to manage data. Through Redux-DevTools, I can observe that initially the data is null but upon refreshing the page, the data successfully populates the store. However, when attempting to retrieve this data within on ...

Utilizing Lodash efficiently with tree shaking

After experimenting with using lodash functions as a specific import versus as a destructured object, I noticed a significant difference in file size. When imported as shown below, the size is only 14.7KB. However, when I tried importing as a destructured ...

Unable to include the variable "$localStorage"

While working on my method in app.js, I encountered the following error: Uncaught Error: [$injector:strictdi] function($rootScope, $q, $localStorage, $location) is not using explicit annotation and cannot be invoked in strict mode http://errors.angula ...

Transferring multiple data between PHP and JavaScript

Here is the code I am using for the on change event: <script> $('.BIR').change(function() { var id = $(this).val(); //get the current value's option $.ajax({ type:'POST', dataType: "json", ...

In TypeScript, the function is failing to retrieve the complete array value

I'm facing an issue with a program that is supposed to piece together all the letters, but it's not functioning correctly. I've tried using the debugger, but it doesn't display any errors. Here's the code snippet: var phrase = [ &a ...

Incorporate a JavaScript script into an Angular 9 application

I have been experiencing issues trying to add a script.js file to angular.json and use it in one component. Adding a script tag directly to my HTML file is not the ideal solution. Can someone suggest an alternative approach or point out what I may be missi ...