Anticipating the outcome of various observables within a loop

I'm facing a problem that I can't seem to solve because my knowledge of RxJs is limited.

I've set up a file input for users to select an XLSX file (a spreadsheet) in order to import data into the database. Once the user confirms the file, various validations are performed on the document before insertion to prevent any issues.

The file is scanned and checked line by line. However, one of my verification processes is causing a dilemma. I need to utilize a database procedure to verify the existence of certain data in the database. The issue arises when the query returns an observer, causing my for loop to iterate through the entire file even before receiving the query result. The console displays 'Import finish' before completing the necessary checks.

I am wondering if there's a way to pause the loop until I receive the result from the subscribe function, or if I can let the loop complete and then finalize the import once all results are obtained.

Component:

importObjectives(): void {
    // Code snippet
}

Store Wallet:

checkWallets(xlsx: XLSXObjective, lineError): Observable<any> {
    // Code snippet
}

Service Wallet:

checkWallets(xlsx: XLSXObjective): Observable<any> {
    // Code snippet
}

Any assistance would be greatly appreciated. Thank you, and please excuse any language errors.

Answer №1

Utilize Observable.forkJoin to create a loop for observables, allowing you to wait for all data to be received from multiple observables.

Observable.forkJoin is ideal when you need to synchronize the responses from multiple HTTP calls.

If you are unsure about the data returned by your HTTP calls, here's a simple example:

    loadedCharacter: {};
  constructor(private http: HttpClient) { }

  ngOnInit() {
    let character = this.http.get('https://swapi.co/api/people/1');
    let characterHomeworld = this.http.get('http://swapi.co/api/planets/1');

    forkJoin([character, characterHomeworld]).subscribe(results => {
      // results[0] contains character data
      // results[1] contains character homeworld data
      results[0].homeworld = results[1];
      this.loadedCharacter = results[0];
    });

Answer №2

Here's my approach:

const observableTasks = [];

fetchDataFromExternalSource(): void {
    if (this.dataFile) {
        if (["xlsx","xls","csv"].includes(this.dataFile.name.split('.').pop())) {
            if (typeof (FileReader) !== 'undefined') {
                const reader = new FileReader();

                reader.onload = (event: any) => {
                    let fileDataArray = new Uint8Array(event.target.result);
                    let workbook: XLSX.WorkBook = XLSX.read(fileDataArray, { type: 'array' });
                    let sheetName: string = workbook.SheetNames[0];
                    let worksheet: XLSX.WorkSheet = workbook.Sheets[sheetName];
                    let parsedData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

                    parsedData.shift();
                    for(var rowData of parsedData) {
                        var rowLineNumber = parsedData.indexOf(rowData) + 2;
                        // Additional validations...
                        observableTasks.push(this.dataProcessingService.checkData(this.XLSXObjective, rowLineNumber))
                    }

                    forkJoin(observableTasks).subscribe(dataResults => {
                      if(this.errors.length > 0) {
                          console.error("Errors encountered:");
                          console.error(this.errors);
                      } else {
                          console.log("Data import completed successfully");
                      }
                    }
                    this.dialogReference.close();
                };
                reader.readAsArrayBuffer(this.dataFile);
            }
        } else {
            console.error("File format not supported");
            this.dialogReference.close();
        }
    } else {
        console.error("No data file provided");
        this.dialogReference.close();
    }
}

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 is the method for defining a mandatory incoming property in an Angular2 component?

In my current project, I am developing a shared grid component using Angular2 that requires an id property. export class GridComponent { @Input() public id: string; } I'm looking for a way to make the id property mandatory. Can you help me with ...

Updating objects in Angular 8 while excluding the current index: a guide

this.DynamicData = { "items": [ { "item": "example", "description": "example" }, { "item": "aa", "description": "bb" }, ...

What advantages does CfnAppSync provide over using AppSync in a CDK project?

We are in the process of enhancing our API by adding new JS resolvers and phasing out the VTL resolvers for an AWS AppSync CDK project, specifically built with Cfn<> Cloud Front CDK. The code snippet below illustrates how this can be achieved: ...

Subscribe to the service in Angular and make repeated calls within the subscription

What is the most effective way to chain subscriptions in order to wait for a result before starting another one? I am looking for something similar to async/await in Javascript, where I need the result of the first call to trigger the next one. Currently, ...

Is it possible for Next.js to retrieve the window size without resorting to a faulty hook call or encountering an undefined window

In my ongoing efforts to dynamically adjust the size of an image within a next.js application to make it responsive to various screen sizes, I have encountered challenges. The different methods I have attempted and observed have resulted in either an inv ...

Angular 15 is unfortunately not compatible with my current data consumption capabilities

I'm currently facing an issue with Angular 15 where I am trying to access the "content" element within a JSON data. However, when attempting to retrieve the variable content, I am unable to view the elements it contains. import { Component, OnInit } ...

Error in Typescript for callback function: The type 'Function' does not match any signature

I am encountering an error stating that Type 'Function' does not match the signature for the filter function below. This is because the filter function expects a specific type. How can I define my callback function to align with what the filter f ...

Error: Unable to access the 'DASH' property as it is undefined

Within my current project, I aim to showcase data related to cryptocurrencies. After making an API call, I successfully obtained a response. The specifications of my environment are as follows: Node: 8.9.5, Express: 4.16.4, Angular CLI: 7.3.6, Typescript ...

How to specify a single kind of JavaScript object using Typescript

Let's say we have an object structured as follows: const obj = [ { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"}, { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"} ] We ...

Tips for including and excluding personalized Chips from input

Just started learning React/typescript, any assistance would be greatly appreciated Custom Chip (CC.chip) is a specialized Chip UI component that can be utilized as demonstrated below. const [isOpen, setIsOpen] = useState(true); const onClose = Re ...

Error encountered in lodash.js in Angular 2 framework

I have been attempting to implement lodash for a datatable. Here are the steps I followed: First, I tried running npm install lodash, but encountered an error stating that the package could not be found After researching the issue, I attempted npm in ...

Is it TypeScript's return type a double arrow (Observable)?

I'm having a hard time understanding this: const loadData: (detailsStore: RecipeDetailsStore) => (source$: Observable<string>) => Observable<RecipeDetails> How should I interpret this? My understanding is: loadData is a function t ...

The error message "ng: command not found" popped up despite successfully installing the latest @angular/cli using npm linking

Here is the information about my current setup: Node version: v10.15.3 NPM version: 6.4.1 I attempted to run the following command: Command: npm i -g angular/cli An error occurred while executing: npm ERR! /usr/local/bin/git ls-remote -h -t ssh:// ...

What is the reason behind typescript making it necessary for me to find a way to set a value of type

function f1() { const v : string = String(); if(v) {alert("IF");} // OK const b : boolean = v; // Type 'string' is not assignable to type 'boolean'. if(b) {alert("BOOLEAN");} } f1(); My approach to this issue involv ...

CORS policy has blocked access to XMLHttpRequest from the origin because the requested resource does not have the 'Access-Control-Allow-Origin' header

I recently built an API project using MVC Core. Everything seemed to be working fine when testing the GET and POST methods with Postman. However, I encountered a CORS error when trying to call these APIs from my Angular App: Access to XMLHttpRequest fro ...

Is Angular2 detecting changes based on value equivalence or reference equality?

I am currently working with Angular2-RC.1 and I've noticed a significant decrease in performance when setting up a component with a large dataset. The component I'm using is a tabular one (which involves Handsontable) and it has an Input property ...

What is the process for validating multiple check boxes using the reactive forms module?

I thought this would be a simple task, but I'm having trouble figuring it out. There are three checkboxes and I need to ensure that the user selects only one. The validator should check if any of the other two checkboxes have been selected and preven ...

Ways to specify a setter for a current object property in JavaScript

Looking to define a setter for an existing object property in JavaScript ES6? Currently, the value is directly assigned as true, but I'm interested in achieving the same using a setter. Here's a snippet of HTML: <form #Form="ngForm" novalida ...

The utilization of rxjs' isStopped function is now considered

We currently have this method implemented in our codebase: private createChart(dataset: any): any { if (!this.unsubscribeAll.isStopped) { this.chart = this.miStockChartService.createChart(dataset, this.chartId, this.options, this.extend ...

Steps for removing the style when a button is clicked

Inside the ngFor loop, I have a button that I am styling as shown below. <div *ngFor="let component of componentList; let index = index"> <button type="button" id='Button{{index}}' name='Button{{index}}' ...