What steps do I need to take to activate the second block in the chain?

I've been working on some code to upload multiple photos to a server.

The code can be broken down into three main parts:

  • First, capturing images from the input file and storing them in a variable until the uploadPictures() method is called.

  • Next, uploading the photos and saving the URLs in an array for later use.

  • Finally, after the uploads are completed and we have the necessary links, updating a specific document in the Firestore database.

The problem I'm encountering is that the code functions smoothly for the first two phases. However, I'm struggling to make it work seamlessly with either async/await or Promises.


async uploadPictures() {

    let loop = new Promise( result => {

      this.files.forEach((file, index) => {

        let path: string = `items/${Date.now()}_${this.files[index].name}`;

        let ref = this.storage.ref(path);

        ref.put(file).then(snapshot => {
          snapshot.ref.getDownloadURL().then(downloadLink => {
            this.url.push(downloadLink);
            console.log('Image is uploaded successfully and available at: ' + downloadLink);
          })
        });
      });

    }).then( () => {

      console.log('hello from here!');
      console.log(this.url);
      this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });

    })


  }


Your insights or suggestions would be greatly appreciated!

Answer №1

After reviewing your code, I noticed a few issues with how you are handling promises. It's common to make mistakes when working with promises, especially if you are new to them, so don't worry too much about it.

The first issue is related to the way you are using the new Promise constructor. This constructor requires a function with two parameters: resolve and reject. These functions are called to either fulfill or reject the promise. In your code, you are not utilizing these functions properly, which results in the promise never being resolved.

The second issue lies in the fact that you have nested promise calls but are not returning the promises up the call chain. This leads to improper chaining of promises.

In this scenario, using new Promise() may not be the best approach. Instead, you should create an array of promises inside the loop and then use Promise.all to ensure that all promises in the array are fulfilled before proceeding.

It might be easier for you to switch to using async/await syntax instead of dealing with explicit promise handling and then calls. The following code snippet demonstrates how you can achieve this using explicit promises:

// No need for async if not awaiting
uploadPictures() {
    // Create an array of promises for each item in the loop using Array.map
    let loop = this.files.map((file, index) => {
        let path: string = `items/${Date.now()}_${this.files[index].name}`;
        let ref = this.storage.ref(path);

        // Inner promise - MUST RETURN THIS for proper chaining
        return ref.put(file)
        .then(snapshot => snapshot.ref.getDownloadURL())
        .then(downloadLink => {
            this.url.push(downloadLink);
            console.log('Image uploaded successfully and available at: ' + downloadLink);
        });
    });
    return Promise.all(loop)
    .then(() => {
        console.log('Hello from here!');
        console.log(this.url);
        return this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
    });
}

Using async/await makes the code cleaner and more concise:

async uploadPictures() {
    // Create an array of promises for each item in the loop using Array.map
    let loop = this.files.map(async (file, index) => {
        let path: string = `items/${Date.now()}_${this.files[index].name}`;
        let ref = this.storage.ref(path);

        // Using await to simplify the code
        let snapshot = await ref.put(file);
        let downloadUrl = await snapshot.ref.getDownloadURL();
        this.url.push(downloadLink);
        console.log('Image uploaded successfully and available at: ' + downloadLink);
    });

    await Promise.all(loop);
    console.log('Hello from here!');
    console.log(this.url);
    await this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
}

I hope this explanation helps you improve your promise handling in the future!

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

Having trouble with Angular 6 sending data to a REST API and receiving a 500 error code

I'm encountering an issue when trying to post data to a REST API as it keeps returning error 500. Oddly enough, when I test the API in Postman, everything seems to be working just fine. https://i.sstatic.net/nmweS.png authentication.service.ts regi ...

What should the expected response be from Angular service observables in cases where an object cannot be found?

I recently encountered a perplexing architectural dilemma involving the utilization of rxjs and observables when engaging with a data service in Angular. Consider the following scenario: displayDetails(id: String): void { this._dataService.getById(id). ...

Limit the number of rows displayed with ngFor

I have an array in Angular and I am using *ngFor to display its items. I would like the items to be arranged in 2 rows with as many columns as possible. It's fine if only 6 items are displayed on the screen. .item { width: 150px; height: 300px; ...

Are Handlebars and Angular 2 compatible?

Since the syntax for Angular expressions and Handlebars expressions is the same ({{ }}), I'm curious if we can utilize both at the same time. ...

Please provide me with the steps to relocate the src/pages/api folder to src/ in a Next.js project

When working with Next.js, I am interested in relocating the src/pages/api directory to be located under src/, much like how it is done in blitz.js. In this case, the directory structure would look something like this: src |- pages |- api Unfortunately, I ...

Options for Angular's routerLinkActiveDirective

I have a link that looks like this <li routerLinkActive="active" class="nav-item"> <a [routerLink]="['contracts']" [queryParams]="{ activeOnly: false }" class="nav-link">Contracts</a> </li> As you can see, in the param ...

Identify the general type according to a boolean property for a React element

Currently, I am facing a scenario where I need to handle two different cases using the same component depending on a boolean value. The technologies I am working with include React, Typescript, and Formik. In one case, I have a simple select box where th ...

Despite passing the same dependency to other services, the dependencies in the constructor of an Angular2 Service are still undefined

To successfully integrate the "org-agents-service" into the "org-agents-component," I need to resolve some dependencies related to the required api-service. Other components and services in the hierarchy are also utilizing this api-service, which acts as a ...

How can you effectively blend Vue/Angular with other JavaScript resources to enhance your development process?

My curiosity lies in understanding how front-end javascript libraries such as Vue and Angular can seamlessly integrate with other libraries and assets. For instance, if I were to procure a website template already equipped with additional javascript, is it ...

Is it recommended to employ cluster connection within my Redis client when utilizing Azure Redis Cluster?

It seems that the Azure documentation on clustering can be a bit confusing. According to the docs: Will my client application need any modifications to support clustering? Once clustering is activated, only database 0 will be accessible. If your client ...

"Exploring the possibilities of Angular 6 through custom pipe

Is there a way to integrate a custom pipe from an Angular 6 library into my main app? I have been attempting to do so in the following manner: @NgModule({ declarations: [ SomePipe ], exports: [ SomePipe ]}) Within public_api.ts: export * fr ...

Can you guide me on how to access an Angular route using a URL that includes query parameters?

Within my current development project, I have implemented a user profile route that dynamically navigates based on the user's _id. This means that when a user accesses the page, their _id is stored in localStorage and then used to query MongoDB for th ...

What are the best ways to utilize .svg images for native script splash screens, backgrounds, icons, and buttons?

I am interested in replacing the .png files I previously used for my native script android app with .svg files. My goal is to utilize svg images for splash screens, backgrounds, icons, and buttons. Thank you! ...

Implementing ordering and limiting of elements in NestJS TypeORM relations

I am new to typeorm and relationships. I am currently facing some challenges and feeling a bit confused. I have a question regarding sorting relations in typeorm by id or createdDate without explicitly mapping them and limiting the number of elements. Here ...

Unlock TypeScript code suggestions for extended objects

In my app, I use a configuration file named conf.ts to consolidate config values from other files for better organization. By merging these values, it becomes more convenient to access them using Conf.MY_LONG_NAMED_VALUE rather than Conf.SubCategory.MY_LON ...

Saving the contents of a JSON query field to a file using Angular

Currently, I am working on an Angular application that interacts with a JSON API to extract specific fields from the data and save them to a file. For instance, if the API query yields: [{"id":1,"name":"Banana"},{"id" ...

The error "Prop does not exist on type 'PropsWithChildren'" occurs when attempting to dispatch an action with react-redux

When attempting to dispatch the action, I am encountering this error: The error message reads: Property 'fetch_feed_loc' does not exist on type 'PropsWithChildren<{ onSubmitForm: any; }>'. Another error states: Property &apos ...

Deliver a modification of the injected variable

I am facing an issue where I provide variables in a component and then try to inject/change them in the child component. Surprisingly, this setup works perfectly fine on the local server but once uploaded to the live server, the variable doesn't seem ...

How to stop an item from being dropped in an undesired list using Angular drag and drop

Exploring the use of Angular Material's drag and drop feature to rearrange items between different lists, like moving them from the Options list to either the Include or Exclude list based on the selected radio button in the Where to move group. http ...

I'm encountering difficulty trying to set up sweetalert2 in Angular

Please provide an image description I'm facing a problem and I need assistance. Despite following various installation guides, I have been unable to find a resolution. Please provide an image description ...