Angular 6 RxJS6 observable failing to retrieve data in correct sequence

While iterating through an array and invoking the LoadReportsData function, I noticed that the calls to getProjectReportsData within _reportingService are made in the correct sequence. However, upon returning from the service map and then using .subscribe(), the code inside it is not executed until all the calls are completed.

As a result, the data is assigned to this.reportData in a random order. This randomness leads to the creation of worksheets in the workbook in a haphazard manner instead of following the intended order. I am seeking suggestions for alternative methods to handle these calls or any workarounds that could mitigate this issue.

FetchProjectSubmissionReportingAssets(ID: number,
        mySelectiontot: number, PRsDelimitedList: string, StartDate: string, EndDate: string) {

        let currAsset: string = '';
        let ID: number;
        var fetchAssetData = {
            'CSID': ID
        }
        this._reportingService.isLoading = true;
        this._reportingService.getProjSubRptAssets(fetchAssetData).pipe(
            map(result => {
                if (result != null) {

                    for (var i = 0; i < result.length; i++) {
                        this.ProjReqSubmissionReportingAssets = result;


                        currAsset = result[i].option;
                        ID = result[i].id;

                        this.LoadReportsData(ID, currAsset, i);

                    }
                }
            }))
            .subscribe();


    }


    LoadReportsData(CSAsID: number, currAsset: string, tabIndex: number) {

        this.wb = XLSX.utils.book_new();

            var indata = {
                'CSID': this.CSID,
                'CSAsID': CSAsID,
                'StartDate': this.StartDate,
                'EndDate': this.EndDate,
                'PRsDelimitedList': this.PRsDelimitedList

            }
            this._reportingService.getProjectReportsData(indata).pipe(
                map(result => {

                        this.reportData = result;

                        this.idx = this.idx + 1;

                        if (this.reportData != null) {
                            this.ws = this.ws + '_' + tabIndex.toString();
                            this.ws = XLSX.utils.json_to_sheet(this.reportData);
                            XLSX.utils.book_append_sheet(this.wb, this.ws, currAsset);
                            console.log(currAsset);
                        }
                        if (this.ProjReqSubmissionReportingAssets.length == this.idx) {
                            var currDateTime = this.fn_getTimeStamp();
                            XLSX.writeFile(this.wb, "ProjReport_" + this.HCs + "_" + currDateTime + ".xlsx");
                        }

                }))
            .subscribe();

            this._reportingService.isLoading = false;

}

Answer №1

Optimize your code by creating an array of API calls and using combineLatest to handle them efficiently. By doing this, the subscriber will receive the data in the correct order without making multiple calls inside a loop.

Consider implementing a structure similar to the following:

    this._reportingService.getProjSubRptAssets(fetchAssetData).pipe(
        filter(result => result !== null),
        map(result => result.map(
            curAsset => this.LoadReportsData(curAsset.id, curAsset, i)
        )),
        switchMap(requestsArray => combineLatest(requestsArray))
    ).subscribe(
        resultArray => {
            // The responses of API calls should align with the initial call order
            // from getProjSubRptAssets(fetchAssetData) method
        })

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

What causes the $injector to be empty while utilizing UpgradeComponent?

I am currently attempting to transition from using Angular 1 to Angular 2 by bootstrapping a hybrid setup that incorporates both ng1 and ng2. You can find the code for my project here: https://plnkr.co/edit/3jrnPyVc8WN2a4crUJF?p=preview Upon running this ...

What is the best way to incorporate a JavaScript file into TypeScript code?

I have developed a JavaScript code called carousel.js with the purpose of adding previous and next events to a carousel. How can I integrate this into my TypeScript project? Below is the render method where I have included some basic HTML markup. publi ...

Issue: Angular 2 is missing the runtime compiler component

In my Angular2 project, I utilized the compiler service to create a dynamic module and render it at runtime in the app. However, an issue arises when I run the command ng build --prod. The process completes without any errors, but upon hosting it on heroku ...

Unable to execute a POST request using the HTTPParams Object

I'm facing a challenge as a newcomer to Angular when it comes to fetching data from a server using the Angular httpClient and HttpParams. While the uri specification works, I am striving for an alternative solution using the HttpParams Object. I&apo ...

Saving files to MinIO from an Angular2 web form

I am currently working on a prototype for an Angular8 application that is capable of uploading files from a form to MinIO. Below is the structure of the form: upload-form.component.html : <input class="form-control" type="file" (change)="onFileCha ...

Angular BehaviorSubject is not refreshing quickly enough

After following a tutorial on creating full Angular + JWT Authentication, I encountered some issues when testing the project. In order to notify the AuthGuard that I am connected and can proceed to the next page upon logging in, I needed to send the API re ...

TypeScript: Utilizing specific objects as function arguments in implementing an interface

To better understand this concept, let's take a closer look at the code snippet provided: interface FooInterface { bar: (flags: { [key: string]: string }) => void; } export class Foo implements FooInterface { bar(flags: { myFlag: string }) {} ...

Ensure that the interface limits the key value to match precisely the value of a constant in Typescript

Seeking assistance in understanding how to enforce a specific type for an optional key within an interface: const FIRST = "FIRST" const SECOND = "SECOND" interface TSomeInterface { element: Element order?: typeof FIRST | typeof ...

What causes Angular projects to only display a single object when using an array?

I've been exploring the League of Legends API, specifically focusing on the champion json data it provides. Currently, I have developed a service using Angular: import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders} f ...

Specifications for TypeScript Columns

Is there a way to create a comprehensive column definition map for various model types with proper typings in JavaScript? Let's explore how to achieve this: export type User = { id: number; admin: boolean; email: string; }; export type Book = { ...

Despite the presence of a producer and topic, sending Kafka messages is proving to be a challenge

Currently, I am using TypeScript and the KafkaJS library on my local machine with a single Kafka broker. After successfully connecting a producer, confirming the creation of my topic, and creating messages like so: const changeMessage = { key: id, ...

Pagination of the Angular Material table connected to a GraphQL server

Looking to implement pagination on an Angular Material table, but facing a challenge with the data response coming from a GraphQL backend. The structure of the data is as follows: import { Component, OnInit, ViewChild } from '@angular/core'; impo ...

Getting the current browser window in the renderer within Electron 14: A step-by-step guide

Previously, I utilized the code below to retrieve the current window from the renderer: import {remote, BrowserWindow} from 'electron'; export function getCurrentWindow(): BrowserWindow { return remote.getCurrentWindow(); } With electron 14 ...

Tips on ensuring a certain HTML tag is used in the component interface

I developed a custom checkbox component that can receive children props from its parent interface CustomCheckboxProps { children?: string; } const CustomCheckbox = (props: CustomCheckboxProps) => { const { children } = props; return ( <di ...

Unique TypeScript code snippets tailored for VSCode

Is it possible to create detailed custom user snippets in VS Code for TypeScript functions such as: someArray.forEach((val: getTypeFromArrayOnTheFly){ } I was able to create a simple snippet, but I am unsure how to make it appear after typing an array na ...

When a card is clicked in the parent component, data is sent to the child component in Angular. The card contains an image, name, ID,

How can I pass data from a parent component (nfts) to a child component (main) when a card is clicked? The card contains images, ids, names, and more information. I've attempted using @Input() but haven't been able to receive the value in the ch ...

Guide to merging the outcomes of multiple observables with concatMap in Angular

After creating four api calls, I made the decision to combine all of their results using the rxjs operator concatMap. The process involved calling each API one by one, pushing all the results for each observable, and then moving on to the next. However, I ...

How can we optimize ternary statements within ternary statements in Type Script and React Native for best practices?

Can you help me optimize this code snippet that uses nested ternary operators for better readability and correctness? <TouchableOpacity style={ darkMode ? filterState === 'A' ? styles.activeButtonDark : styles.buttonDa ...

A TypeScript object with user-defined keys

I have a question about utilizing TypeScript records with a custom Type as keys. Essentially, I have a specific type (a limited set of strings) that I want to use as keys for my record. My goal is to start with an empty initialization of this record. type ...

Angular is having trouble properly rendering the Array Description

I'm currently working on a project using .net core MVC with an Angular frontend. I am facing an issue where the description of parameter arrays is not displayed in the output, even though single parameters display correctly. How can I resolve this pro ...