Flatten Angular Promises in a Synchronous Manner

Is there a way to run a series of promises synchronously, ensuring that the second promise is not executed until the first one is completed? I need to load data in chunks of 10 clients each and display the first N clients while the rest are loading.

I want to avoid having to explicitly chain processChunk1().then(() => processChunk2()) as shown below. Instead, I am looking for a solution where the chunks can be processed in a loop until all clients are loaded. Any suggestions would be greatly appreciated!

loadPerformanceDtos(): ng.IPromise<{}> {
    var deferred = this.$q.defer();
    var clientList: any = [];

    $.extend(clientList, this.$location.search().client);

    // Convert single client search into an array
    if (!angular.isArray(clientList)) {
        clientList = [clientList];
    }

    var that = this;

    var sortedClients: string[] = (<string[]>clientList).sort();
    const chunkSize: number = 10;

    this.performanceDtoModels = [];

    var chunk1: string[] = sortedClients.splice(0, chunkSize);
    var chunk2: string[] = sortedClients.splice(0, chunkSize);
    var chunk3: string[] = sortedClients.splice(0, chunkSize);

    processChunks([chunk1, chunk2, chunk3]).then(() => {
        processChunks([sortedClients]);
    });

    function processChunks(chunks: string[][]) {
        var chunkDeferred = that.$q.defer();

        if (chunks.length === 0) {
            chunkDeferred.resolve();
        } else {
            var chunk = chunks.shift();
            
            that.performanceService.loadPerformanceData(chunk)
                .success((data: IPerformanceDtoModel[]) => {
                    data.forEach((item: IPerformanceDtoModel) => {
                        that.performanceDtoModels.push(item);
                    });
                    
                    chunkDeferred.resolve();
                });
        }

        return chunkDeferred.promise;
    }

    return deferred.promise;
}

Answer №1

One approach to handle this situation is by utilizing a recursive function that triggers itself with a subset of the original list once each asynchronous operation is completed. The code snippet below showcases an example implementation where processChunks recursively calls itself following each async task execution.

However, it's worth noting that this specific implementation overlooks scenarios where the async method encounters errors or doesn't include any mechanism to track the completion status of all chunks. To address the latter issue, additional logic would need to be incorporated to identify when the final chunk has been fully loaded.

class YourClass {

    loadPerformanceDtos(): ng.IPromise<{}> {
        this.loadDeferred = this.$q.defer();

        var requestedClients: string|string[] = this.$location.search().client;

        var clientList: string[];
        if (!angular.isArray(requestedClients)) {
            clientList = [requestedClients];
        } else {
            clientList = requestedClients;
        }

        clientList.sort();
        this.performanceDtoModels = [];
        this.processChunks(clientList, 10);
    }

    processChunks(list: string[], size: number) {
        var chunk = list.slice(0, size);

        // Resolving the progress bar for the initial page
        if (this.performanceDtoModels.length > 0) {
            this.loadDeferred.resolve();
        }

        if (chunk.length > 0) {
            this.processChunk(chunk).then(() => {
                this.processChunks(list.slice(size), size);
            });
        }

    }

    processChunk(chunk: string[]) {
        var deferred = this.$q.defer();
        
        if (chunk.length === 0) {
            deferred.resolve();
        }
        else {
            this.performanceService.loadPerformanceData(chunk)
                .success((data: IPerformanceDtoModel[]) => {
                    data.forEach((item) => {
                        this.performanceDtoModels.push(item);
                    });

                deferred.resolve();
            });
        }

        return deferred.promise;
    }
}

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

VSCode prioritizes importing files while disregarding any symbolic links in order to delve deeper into nested node

I'm encountering a problem with VSCode and TypeScript related to auto imports. Our application includes a service known as Manager, which relies on certain functions imported from a private npm package called Helpers. Both Manager and Helpers make us ...

The map functionality is failing to render on the three.js object

function generate_geometry(scene) { var mesh; var material; var texture; var geometry; geometry = new THREE.BufferGeometry(); geometry.attributes = { position: { itemSize: 3, array: ...

I'm experiencing an issue with redirect in Nextjs that's causing an error message to appear. The error reads: "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

I'm currently diving into the world of NextJS and working on creating a simple recipe application. Utilizing the new App Router has been smooth sailing for the most part, except for one hiccup with the login function. After successfully logging in (us ...

`How can I sort information based on a chosen parameter?`

Is it possible to combine the two conditions into one within the function onSelectedReport()? Representing these conditions in HTML would result in: HTML: <div *ngFor="let report of reports"> <div *ngFor="let i of income"> <di ...

Displaying each character of text individually with jQuery

I am trying to display the text within a ul tag one by one when hovering over some text. However, I am encountering an error. How can I resolve this issue? You can view the code for mouseover functionality by hovering over the "hover here hover again" lin ...

Validation of Style

Is there a way to translate the following CSS code into JavaScript? Basically, I want it to apply the style rules after the onchange event. .appnitro input:required:valid, .appnitro textarea:required:valid { box-shadow: 0 0 5px #5cd053; border-c ...

Is there a way for me to ensure that my text labels always face the camera? Maybe by utilizing sprites?

I have been experimenting with combining canvas interactive objects and mouse tooltips in my project. I am trying to generate text labels on rotating cubes, but I am facing some issues. The text moves along with the cubes' rotation and sometimes appea ...

Is there an issue with implementing autosuggestion and tagging functionalities in jQuery?

My script is designed to suggest values based on user input and then convert the selected value into a tag. However, when a value is selected from the drop down menu, only the first 2 or 3 characters are tagged. You can see the script in action on js fiddl ...

Tips for removing a previous file from an 'input type' in HTML5 FileReader

Here is a file input with an associated function: <img id="uploadPreview"> <div id="changeImage">Change</div> <div id="customImage"> <input type="file" id="myfile" multiple style="display:none" onchange="PreviewImage();" / ...

The type error in my nestjs application is caused by my attempt to access the property _id on the result of a promise, which does not exist on the type

Within my current project, I am encountering a type error when attempting to call _id on the user object. This issue arises because mongoose automatically defines the _id, meaning it is not present in my schema where the promise is defined. Upon changing ...

"Troubleshooting the issue of jQuery failing to set data

Although it seems straightforward, I am puzzled as to why this code is not functioning properly. The selector is accurate, but for some reason the .faqContent div is not being updated with the data-height attribute. $('.faqItem .faqContent').eac ...

Despite applying a CSS reset in the modal, the margin-bottom property is still being recognized in Chrome but not in Firefox

Here is a snippet of CSS code that I am currently working with: * { margin: 0; padding: 0; } body { overflow-x: hidden; margin: 0; padding: 0; } .modal { display: none; position: fixed; z-index: 1; left: 0; top: 0; right: 0; bott ...

What is the best way to transfer data received from a controller to Express' router?

Seeking assistance in creating a versatile function to handle data retrieval for my Author endpoint. The goal is to return a complete list of authors if the URL passed to the endpoint has no query parameters. If the URL includes firstName and lastName para ...

Modify the code to use a BehaviorSubject subscribing to an Observable

Currently, I am in the process of learning Angular2 and RxJS by studying someone else's application. The application consists of two modules: asObservable.ts export function asObservable(subject: Subject) { return new Observable(fn => subject ...

Increased accuracy in wildcard regexp usage

I wrote a script that uses wildcards to filter filenames. For example, using `*.js` will give me all the JavaScript files in a directory. However, I encountered an issue where it also includes `.json` files in the results, which is not what I intended. T ...

How to remove decimal points from the x-axis in jqPlot

Is there a way to show only whole numbers on the x-axis in jqPlot? At the moment, it shows: 0.5, 1, 1.5, 2, 2.5, etc. I'm looking for a method to make it display integers exclusively in the x-axis labels. ...

Is it possible to target elements based on a specific CSS3 property they use?

Is there a method to target all elements in the DOM with a border-radius other than 0? If anyone has suggestions, it would be greatly appreciated! ...

After calling sequelize.addModels, a Typescript simple application abruptly halts without providing any error messages

My experience with Typescript is relatively new, and I am completely unfamiliar with Sequelize. Currently, I have only made changes to the postgres config in the .config/config file to add the dev db configuration: export const config = { "dev" ...

I am encountering an issue where JSON.parse is returning undefined when trying to

Upon receiving a string from my server, I am attempting to parse it into a JSON object. Here is the string and relevant code snippet: stringToParse = "\"{'female': 16, 'brand': 75, 'male': 8}\"" d ...

Issues with unchecking modal icheck box when closing in Bootstrap JavaScript

Here is the HTML code that I am working with: <div class="modal inmodal" id="handleUserModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog"> &l ...