Expectation in Observable: Unable to provide data retrieval

In my Angular 7 and Typescript project, I am faced with the challenge of reading a json file from within a zip file. Although I am able to successfully display the correct json output on the console, I am struggling to return this json data from the function.

My approach involves downloading the zip file using a separate service that utilizes an observable. Within this observable, I make use of a promise provided by the JSZip library to extract the zip file and access the json data. Below is the code snippet for the function responsible for this task:

extract-zip.service.ts:

async getJSONfromZip(zip_filename: string, json_filename: string) {
    return this.fileService.downloadResource(zip_filename)
    .pipe(
      map (async (data: any) => {
        return JSZip.loadAsync(data)
          .then((zip: any) => {
            Object.keys(zip.files)
            // iterate over all containing files
            .forEach((filename) => {
            // look for json file
            if (filename === json_filename) {
              return zip.files[filename].async('string')
                .then((fileData: any) => {
                  console.log(fileData);

                  return fileData;
              });
            }
          });
      });
    }))
    .toPromise();
  }

Although the function currently returns a Promise, my goal is to actually retrieve and return the content of the json file (fileData). Despite trying various approaches such as converting it to a Promise or utilizing and returning a class member variable, I have yet to find a solution.

Answer №1

I'm uncertain why you're treating it as a promise, so I've opted to keep everything as observables until the very end.

async fetchJSONfromZip(zipFileName: string, jsonFileName: string) {
    return this.fileService
      .downloadResource(zipFileName)
      .pipe(
        switchMap(data => from(JSZip.loadAsync(data))), // convert the promise into an observable
        map(zip => {
          const fileNames = Object.keys(zip.files);
          const fileExists = fileNames.find(fileName => fileName === json_fileName);
          if (fileExists) {
            return zipFiles[fileName];
          } else {
            return undefined;
          }
        }),
        filter(zipFile => zipFile), // don't proceed if the file isn't found
        switchMap(zipFile => from(zipFile.async('string')))
      )
      .toPromise();
  }

const myJsonData = await fetchJSONfromZip('something.zip', 'json_name.json');

Keep in mind that your promise might never be fulfilled; if necessary, consider removing the filter and throwing an exception instead.

I suggest using observables over promises for better handling.

Answer №2

It appears that there is a problem with not fulfilling your promise as expected. It should be handled in the following manner:

To resolve this, please wait for the function to execute:

async getJSONfromZip(zip_filename: string, json_filename: string) {
    var promise = this.fileService.downloadResource(zip_filename)
    .pipe(
      map (async (data: any) => {
        return JSZip.loadAsync(data)
          .then((zip: any) => {
            Object.keys(zip.files)
            // iterate over all containing files
            .forEach((filename) => {
            // look for json file
            if (filename === json_filename) {
              return zip.files[filename].async('string')
                .then((fileData: any) => {
                  console.log(fileData);

                  return fileData;
              });
            }
          });
      });
    }))
    .toPromise();

     await promise;
  }

Alternatively, you can use the following code snippet to wait for the function to complete:

var output = await getJSONfromZip(filename,jsongfilname);

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

Issue: Unable to import certain modules when using the Typescript starter in ScreepsTroubleshooting: encountering

Having trouble with modules in the standard typescript starter when transferring to screeps. One issue is with the following code: import * as faker from 'faker'; export function creepNamer() { let randomName = faker.name.findName(); return ...

The beta version of Angular 2.0 introduces the BrowserDomAdapter for easy access to the DOM

I have a Component in Angular 2.0 that is attempting to utilize the DOM Adapter API from Angular's BrowserDomAdapter documentation. The initialization of this DomAdapter can be found here. However, I am uncertain about whether the Dom Adapter needs t ...

Endpoint path for reverse matching in Mongodb API

I am currently in the process of setting up a webhook system that allows users to connect to any method on my express server by specifying a method and an endpoint to listen to (for example PUT /movies/*). This setup will then send the updated movie to the ...

Identifying imports from a barrel file (index.ts) using code analysis

Can anyone help me understand how the Typescript compiler works? I am trying to write a script that will parse each typescript file, search for import declarations, and if an import declaration is using a barrel-file script, it should display a message. Af ...

Angular breadcrumb component for creating a sidebar menu navigation

I am looking to enhance my sidebar menu with breadcrumb navigation. The menus currently include Menu1 and Menu2, each containing submenus such as subMenu1 and subMenu2. When a user clicks on Menu2, I want the breadcrumb trail to display as Home > Menu2 ...

Explaining the concept of SwitchMap in RxJS

Currently, I am utilizing Restangular within my Angular 5 project. Within the addErrorInterceptor section, there is a code snippet that invokes the refreshAccesstoken method and then retrieves the new access token in the switchMap segment. My approach invo ...

Encountering a Next.js TypeScript Build Error related to the Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' issue

`I am currently working on a project in Next Js using TypeScript. During the build process with npm run build, I encountered the following errors in the terminal: # Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' do ...

Using Angular2 to perform search functions within the Loopback framework

Can anyone assist me with implementing a "wildcard" query using loopback to search data from the database in my angular2 project? Thank you in advance for your help. This is the query I am trying to use: this.model.find({ "where": { "wildcard ...

What steps do I need to take to mark an Angular form field as invalid using manual input?

I need help with a login form validation issue. When a user enters invalid credentials, I want to mark both the email and password fields as invalid and display a message indicating that the login failed. Can anyone guide me on how to achieve this using an ...

Encountering an uncaughtException: Error stating that the module '....nextserverapphomelibworker.js' cannot be located while attempting to utilize pino.transport in Next.js

I recently set up a Next.js project with typescript using create-next-app. Opting for Pino as the logging library, recommended by Next.js, seemed like the logical choice. Initially, when I utilized Pino without incorporating its transport functionality, e ...

Transform Firestore JSON data into a TypeScript array

Extracting and formatting data from Firebase for visualization purposes can be challenging after successfully working with it in HTML. I am currently dealing with a FirebaseListObservable that contains three value-types, but only one of them needs to be in ...

Is it necessary for an Angular service's query method to return an error when it doesn't find any

Let's say I create a service that includes a method called getProducts When using this service, it looks something like this this.service.getProducts('someProduct').subscribe(product => {}, err => {}); If the product with the name & ...

What is preventing you from utilizing TypeScript's abstract classes for generating React factories, especially when regular classes seem to function properly?

Here is an example showcasing the behavior of TypeScript code using React with abstract classes: import * as React from "react"; class MyComponent<P> extends React.Component<P, any> { static getFactory() { return React.createFacto ...

Failure of VSCode breakpoints to function properly with TypeScript npm linked package

I am developing a Next.js app using TypeScript and my .tsconfig file includes the following configurations: { "compilerOptions": { "baseUrl": "src", "experimentalDecorators": true, "target": & ...

I have implemented the ag grid date filter, but I am having trouble getting the apply and reset buttons to work properly within the filter

Currently, I am facing an issue with the ag grid date filter implementation. I am attempting to add both apply and reset buttons to the filter, but the code I have used does not seem to be functioning correctly. Here is the column definition code snippet ...

Unable to locate module src/ in Node.js TypeScript

I'm encountering issues with non-relative imports in my node.js / typescript application. Here is my tsconfig: { "compilerOptions": { "target": "es6", "module": "commonjs", "lib": ["dom", "es6", "es2017", "esnext.asynciterable"], "s ...

What are the steps to avoid TypeScript from automatically installing and referencing its own @types in the AppDataLocal directory?

I'm encountering a perplexing issue where it appears that TypeScript is setting up its own version of React in its unique global cache system (not entirely sure what to call it? presuming that's the case) and utilizing it within my project. In p ...

Create a tuple type that encompasses all possible paths within a recursive object configuration

Consider the following templates for 'business' types, representing compound and atomic states: interface CompoundState<TName extends string, TChildren extends { [key: string]: AnyCompoundState | AnyAtomicState }> { type: 'parent&ap ...

acquiring environmental variables in TypeScript for node applications

I am struggling with accessing process.env variables in my TypeScript pages. It seems to be a scope issue, which doesn't make sense to me as a beginner in TypeScript. To get my environment variables, I use a YAML file and attach them to the running p ...

Unable to display custom component on app.component.html

After creating a unique custom component named core.component, I proceeded to import it into a module with the same name. core.component.html <div class="container-fluid text-left"> <div class="row rows-cols-2 top-bar"> ...