Using Observables within a for loop?

I need to call a REST service that returns base64 encoded CSV files in a for loop. I then decode and concatenate these files into one string before returning it. However, when I try to subscribe to this method and download the file by clicking the DOM, I only get an empty string with "\r\n" in it. Why doesn't it wait for the REST service to return the file before proceeding?

downloadFilesAndConcatenate(): Observable<any> {
    let concatenatedFileDecoded: string = '\r\n';
    for (let i = 0; i < this.fileIDs.length; i++) {
      this.restService.getFile(this.fileIDs[i]).subscribe(response => {
        this.fileResultSet = response;
        this.message = response.message;
        this.file = this.fileResultSet.result;
        let fileCSVbase64 = this.file.fileBytes
        let fileCSVDecoded = atob(fileCSVbase64);
        concatenatedFileDecoded += fileCSVDecoded;
      },
      error => {
        this.message = error.error.message;
      });

      return new Observable( observer => {
        observer.next(concatenatedFileDecoded)
        observer.complete();
      });
    }
  }

Afterwards, I attempt to subscribe to it:

download() {
    if (this.dateEnd !== null && typeof this.dateEnd !== "undefined") {
      debugger;
      this.downloadFilesAndConcatenate()  // Multiple files
        .subscribe( 
          (result) => {
            debugger;
            const link = document.createElement( 'a' );
            link.style.display = 'none';
            document.body.appendChild( link );

            const blob = new Blob([result], {type: 'text/csv'});
            const objectURL = URL.createObjectURL(blob); 

            link.href = objectURL;
            link.href = URL.createObjectURL(blob);
            link.download =  this.file.name;
            link.click();
          },
          (err) => {
            console.error(err);
          },
          () => console.log("download observable complete")
        );
    } else {
      this.downloadFile();  // Only one file
    }
  }

Answer №1

since this is asynchronous code, the expectation is that synchronous code will be executed before asynchronous code. here's how the correct code should look like:

downloadFilesAndConcatenate(): Observable<string> {
    return forkJoin(this.fileIDs.map(id => this.restService.getFile(id))).pipe(
      map(responses => '\r\n'+responses.map(r => atob(r.result.fileBytes)).join(''))
      catchError(e => this.message = e.error.message)
    );
  }

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

Angular 2 integrating seamlessly with Django

I am looking to combine Angular 2 with Django and have a few inquiries. How can I adjust the interpolation syntax in Angular 2 from {{ }} to (( )) or something similar? How can I include the CSRF token from a cookie in every HTTP post request? In An ...

Can we verify if strings can serve as valid property names for interfaces?

Let's consider an interface presented below: interface User { id: string; name: string; age: number; } We also have a method defined as follows: function getUserValues(properties:string[]):void { Ajax.fetch("user", properties).then( ...

Unpacking JSON Objects in Typescript: Working with Private Variables

I have a TypeScript model object called user export class User { constructor( private _name: string, private _email: string ) {} public get name():string { return this._name; } public set name(value:string) { this._name = value; } g ...

When a property is given, it must be accompanied by another property

My goal is to design an interface that includes two optional properties, but if one is provided, the other must also be included. For example: interface Link { url: string; } interface LinkWithImage extends Link { imageUrl: string; alt: string; } ...

What exactly do Option and the type [x: string] represent in TypeScript?

Currently, I am delving into the world of TypeScript and finding myself at a bit of a beginner's crossroads. In an effort to expedite my learning process, I have taken to dissecting various coding projects. However, I am encountering some difficultie ...

Can you point me to the location where the 'req' parameter is specified?

I've been exploring a new authentication approach detailed in this article. One issue I'm encountering is locating where the req parameter is declared in the snippet below. It seems like my code won't compile because this parameter isn&apos ...

Angular II slash avoiding Pipe

I am working on developing a customized pipe in Angular 2 that will handle the replacement of the backslash ('\') character in a given string. This backslash is commonly used to escape special characters. What I have accomplished so far: T ...

I require a duplicate of the original data. Direct references are unnecessary

I am trying to extract the value of data.notes. After implementing the code below, I noticed that the detailsOfCurrentNotes value changes based on the data.notes. Can anyone provide guidance on how to resolve this issue? notes :Note[] const detailsOfCur ...

Opening a modal from a different component in Angular 6

I am attempting to launch a modal that is associated with a separate component. However, I encountered an error ERROR TypeError: Cannot read property 'show' of undefined Here is my code: product-catalog.component.html <app-cart-table-modal& ...

Exploring the Possibilities of Retrieving an Array within an Object in Angular 2

After retrieving this array from my database : https://i.sstatic.net/OKrCH.png This function is used to fetch the data : getMembers(){ this.db.list(`projects/${this.auth.userId}/${this.uploadService.pro.name}/teams/`).snapshotChanges().pipe( map( ...

Instructions for linking a string to a mat-checkbox

I have implemented mat-checkbox in my application, but I am struggling to receive a string from the checkbox instead of a boolean. After consulting the Angular Material checkbox API on their website here, I found that there is a 'value' propert ...

TypeScript introduces a new `prop` method that handles missing keys in objects

Is there a way to create a prop function that can return a default type if the specified key is not found in object o? type Prop = <K, O extends {}>(k: K, o: O) => K extends keyof O ? O[K] : 'Nah'; /* Argument of type 'K ...

Issues arise when dynamically generated <input> elements are not displaying on the webpage

I am facing an issue with rendering a form dynamically using a string in my Angular application. Upon clicking the "Add Step" button, the template string is supposed to be added to a list and displayed using ngFor directive. However, I am only seeing the ...

Guide on validating multiple preselected checkboxes using Angular 8 reactive forms

I have a problem with validating checkboxes in my Angular application. The checkboxes are generated dynamically from an array using ngFor loop, and I want to make sure that at least one checkbox is selected before the form can be submitted. The validatio ...

Set up a SQS queue to receive notifications from an SNS topic located in another AWS account by using AWS CDK in TypeScript

Looking to establish a connection between an SQS queue and an SNS topic located in a different account using CDK (TypeScript). Presented below is the code snippet (contained within a stack) that I believe should facilitate this integration. However, I have ...

The error message "TypeError: Object(…) is not a function at index.js" indicates that

Recently, I transitioned from angular 4.4 to angular 7 in my Ionic project. Here's a snippet from my package.json: { "name": "mobile", "version": "0.0.0", "license": "MIT", ... } After deleting node_modules and package-lock.json, I ran npm ...

A versatile function catered to handling two distinct interface types within Typescript

Currently, I am developing a React application using TypeScript. In this project, I have implemented two useState objects to indicate if an addon or accessory has been removed from a product for visual purposes. It is important to note that products in thi ...

Checkbox from Ant Design placed inside a button

As a beginner in React, I am trying to transform an Ant Design Checkbox into a button while maintaining the checkbox functionality. Here is my initial code for the checkbox: import { Checkbox } from "antd"; <div className="modal-body d-flex flex- ...

A guide to mocking Prisma using Jest mock functionality

Utilizing prisma for database interactions and eager to implement jest-mock to simulate the findMany call. https://jestjs.io/docs/jest-object#jestmockedtitem-t-deep--false brands.test.ts import { PrismaService } from "@services/mysql.service"; i ...

Error: React is throwing a SyntaxError because a ")" is missing in the argument list

While working on a React-typescript project using Vite, I encountered an issue where my page was displaying blank and showing the error : Uncaught SyntaxError: missing ) after argument list (at main.tsx:6:51) This error was found in the main.tsx file : im ...