How can I implement a promise loop in Angular that continues until it encounters a rejection?

My goal is to efficiently load around 10000 resources, but loading them all at once during the resolve phase is taking too long due to some calculations. I then had the idea to load the resources page by page sequentially, however, since all resources need to be visible on a map, standard user-input based pagination is not suitable.

I am aware that promises can be chained using:

promise.then(doThis).then(doThat).then(doWhat);

And I also know that an array of promises can be resolved with $q.all like:

$q.all([doThis, doThat, doWhat]);

However, what I want to achieve is to repeatedly call the same promise in a series until it encounters a rejection.

For example:

function next() {
  var deferred = $q.defer();
  if(someCondition) {
    deferred.reject();
  } else {
    //do something
    //store data somewhere
    deferred.resolve();
  }

  return deferred.promise;
}

Imagine that this function makes some $http calls and saves the result in a service/controller. If it reaches a certain condition (like no more pages or an HTTP error), it will reject a promise; otherwise, it will resolve it.

Now, I would like to implement something like this pseudocode:

$q.loop(next).untilError(handleError);

Where the next function will be called in a loop after resolving the previous next call until it encounters a rejection.

Is it possible to achieve this kind of functionality?

Answer №1

Be sure to check out the demo on the console: JSFiddle.

This demo ensures that the API calls use the `userId` from 1 to 5 in sequence. It stops when a certain condition is met (userId > 5).

angular.module('Joy', [])
    .controller('JoyCtrl', ['$scope', '$http', function ($scope, $http) {

    getUser(1, getUser);

    function getUser(userId, next) {
        if (userId > 5) {
            console.log('Enough. Stop');
            return;
        }
        $http.get('http://jsonplaceholder.typicode.com/posts?userId=' + userId).then(function (data) {
            console.log(data.data);
            next(userId + 1, next);
        });
    }
}]);

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

Link a distinctive number to a specific element

I am searching for a method to link a DOM element with a distinct number that is not assigned to any other element in the DOM. Using an Id attribute is not an option as not all elements possess such an identifier. One potential approach is to obtain a num ...

What sets apart toBeInTheDocument from getBy* in @testing-library/react?

Can you distinguish between these two methods in react-testing-library? expect(screen.queryByText('<something>')).toBeInTheDocument(); And screen.getByText('<something>'); (The specific getBy* and queryBy* operation are no ...

Tips for adjusting the alignment of the Vuetify component "VDatePicker" based on the position of its parent component on the screen

Currently, I am utilizing the VMenu component from Vuetify which contains another Vuetify component called VDatePicker. The issue arises when clicking on a text field triggers the appearance of the calendar (VDatePicker). Normally, the VDatePicker componen ...

Skipping element submission in AngularJS when the element is hidden

I am facing an issue with a dropdown list containing enum values. Even when the dropdownlist is hidden using ng-show, the value is still being submitted as ''. As a result, I am encountering the following error: org.codehaus.jackson.map.JsonMapp ...

Utilizing winston to generate multiple log files with set maximum sizes and daily rotation

Currently, I am utilizing winston for logging with a maximum size and daily rotation. I am interested in having this functionality with one file per API endpoint to define multiple log files. Is there a way to achieve this? Displayed below is my winston ...

Can VueJS lifecycle hooks be outsourced?

Is it possible to organize lifecycle hooks (like created / mounted) in a separate file for better simplicity and cleanliness? MyGreatView.vue import created from 'created.js' export default { created, // created() { console.log('vue Cre ...

What is the process for activating my redux function within a component?

I'm working on a form that should create a new user when submitted. In my handleCreate function, I want to use Redux to trigger the addUser action and update the state to add the new user. However, it seems like I'm having trouble calling the act ...

Create a seamless transition between point X,Y and point X1,Y1 through animated movements

Is there a way to smoothly move an image (or element) from its current X, Y position to X1, Y1? If the difference between X and X1 is equal to the difference between Y and Y1, it's straightforward. But what if the X difference is 100px and the Y diff ...

Error in Sequelize and Express JS: Cannot access undefined properties while attempting to read 'findAll'

I am currently facing an issue while working with Express JS and Sequelize in connection to a MSSQL database. The error message "Cannot read properties of undefined (reading 'findAll')" is blocking me from making any requests. Can anyone provide ...

Setting the default type of an array in props in Vue 2 is a common need for many developers

My Vue component relies on an array of objects as a prop and I always make use of prop validation, especially for setting default values. In this case, my current setup is: props: { items: Array } However, I would prefer it to resemble something lik ...

Implementing Laravel pagination to retrieve data through ajax calls

I am currently working on setting up a pagination feature using Laravel. When it comes to the backend, I have set up my JSON response in the following way: if(isset($request->myDate)) { $request->validate([ ' ...

How can I trigger a PHP function by clicking a button on a PHP page that has already been loaded?

While I've come across a variety of examples, I haven't been able to make them work for the simple task I need to accomplish. The code in these examples seems overly complex compared to what I require. In essence, I have a form that processes dat ...

Trouble updating outside controller data while using AngularJS directive inside ng-repeat loop

I am currently working with a isolate scope directive that is being used inside an ng-repeat loop. The loop iterates over an array from the controller of the template provided below: <!DOCTYPE html> <html> <head> <link rel="sty ...

Designate categories by utilizing the x-amz-tagging request header

I'm in the process of creating a Node program to upload files to aws s3, and I'm having trouble figuring out how to specify the x-amz-tagging with the request header. I attempted a solution, but it's not working as expected! function crea ...

What is the best way to create hover effects on buttons in Vue.js 3?

I'm currently developing a calculator to practice my Vue.js 3 skills (I am new to vue). I've successfully implemented the basic features, but now I'm exploring how to incorporate hover animations on the buttons. Specifically, I want to diffe ...

Retrieve the next 14 days starting from the current date by utilizing Moment.js

Looking to display the next 14 days in a React Native app starting from today's date. For example, if today is Friday the 26th, the list of days should be: 26 - today 27 - Saturday 28 - Sunday 01 - Monday 02 - Tuesday ............ 12 - Friday Is ther ...

Angular first renders a component before removing another one using ng-If

I have two components that are displayed one at a time using an ngif directive. <app-root> <first-Comp *ngIf="showFirst"></first-Comp> <second-Comp *ngIf="!showFirst"></second-Comp> </app-root> Here are some key ...

Verify FileReader.onload function using Jasmine and AngularJS

I have a unique directive specifically designed for uploading and importing binary files. This directive listens for a change event on an <input type="file"../> element. Currently, I am facing an issue with the code coverage of my test. Although the ...

Is it possible for Vue to retrieve refs on mounted during nextTick following the dynamic import of the component?

Utilizing Nuxt js and Element UI, I have dynamically imported Element UI plugins in the plugins folder. export default () => { Vue.component("ElForm", () => import("element-ui/lib/form")); Vue.component("ElFormItem", ...

The contents of the $localStroage array do not align with those of the $scope array

I am storing objects in a `$localStorage` array for persistence. I have a check function to see if an object is already present in the array before adding or removing it (using `splice` if present, and `push` if not). However, after refreshing my page, th ...