then() will execute before all promises in promise.all() are resolved

Implementing the async-await technique to handle the promises, I encountered an issue where then() is being called before the completion of Promise.all().

Revised

After changing from Promise<void> to Promise<string>, the problem persists with then() executing prematurely.

// This function uploads an image and returns its path
private async imageUpload(): Promise<string> {
    try {
      let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
      img.subscribe((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // displays url
        return this.bg_img_url.value
      })
   }
}

// This function uploads an icon and returns its path    
private async iconUpload(): Promise<string> {
  try {
      let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
      icon.subscribe((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // shows url
        return this.item_icon.value
      })
   } 
}

The issue arises when trying to access values at a later stage

Promise.all([this.iconUpload(), this.imageUpload()])
      .then((x) => {
        console.log(this.bg_img_url.value) // ''
        console.log(this.item_icon.value) // ''
})

Is there a way to ensure that promise.all() resolves before triggering then()?

Appreciate all the time and effort dedicated to helping me with this problem. Thank you for your valuable input!

Answer №1

It is important to consider the use of promises in conjunction with async/await and make a decision based on your preferred approach.

Option 1 - Simply utilize the promise itself and eliminate the async/await decorators.

Option 2 - Omit then from the promise, as await guarantees that your code will pause until the promises are resolved:

async someFunction() {
...
await Promise.all([this.iconUpload(), this.imageUpload()])
... You can access the resolved values from your promises here
console.log(this.bg_img_url.value) // ''
console.log(this.item_icon.value)
}

Answer №2

EASIEST METHOD
Indeed, considering that subscribe is synchronous. This approach will also be effective

// after image upload, return the path
private async imageUpload(): Promise <string> {
  try {
    let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
    img.subscribe((path: string) => {
      this.bg_img_url.setValue(path)
      console.log(this.bg_img_url.value) // shows the URL
    })
    return this.bg_img_url.value
  }
}

// after icon upload, return the path    
private async iconUpload(): Promise <string> {
  try {
    let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
    icon.subscribe((path: string) => {
      this.item_icon.setValue(path)
      console.log(this.item_icon.value) // shows the URL
    })
    return this.item_icon.value
  }
}

ALTERNATIVE SUGGESTIONS
You could modify both functions to return a Promise like so

// after image upload, return the path
private async imageUpload(): Promise <string> {
  return new Promise(resolve => {
    try {
      let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
      img.subscribe((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // shows the URL
        resolve(this.bg_img_url.value)
      })
    }
  })
}

// after icon upload, return the path
private async iconUpload(): Promise <string> {
  return new Promise(resolve => {
    try {
      let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
      icon.subscribe((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // shows the URL
        resolve(this.item_icon.value)
      })
    }
  })
}

OR you can opt for the rxjs method as shown below

// after image upload, return the path
private async imageUpload(): Promise <string> {
  try {
    let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
    img.pipe(
      switchMap((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // shows the URL
        return this.bg_img_url.value
      })
    ).toPromise()
  }
}

// after icon upload, return the path
private async iconUpload(): Promise <string> {
  try {
    let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
    icon.pipe(
      switchMap((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // shows the URL
        return this.item_icon.value
      })
    ).toPromise()
  }
}

Answer №3

Attempting to retrieve a result within the subscribe method may not work as functions do not wait for the execution of the subscribe method. One approach is to utilize forkJoin when dealing with 2 Observable results, as shown in this example. Alternatively, you can return promises from Observable variables.

For example:

// Return promise from imageUpload
return img.toPromise();

// Return promise from iconUpload
return icon.toPromise();

Promise.all([this.iconUpload(), this.imageUpload()])
  .then((x) => {
      console.log(x);
});

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

Fetching information from a JSON source and storing it within an array of

I am currently facing an issue where I am unable to assign Exercise[] to Exercise. My goal is to retrieve data from a file, create a class object with the JSON values, and then add it to the class array to display as hardcoded JSON data. As someone who i ...

Using TypeScript: Inclusion of all object keys that correspond to a particular type

When working with an object type (or class type), I am looking to create a function that will take the object and a list of its keys as parameters. However, I specifically want to restrict the keys to only those that are mapped to a value of a certain type ...

I am interested in retrieving a particular item from the data() function in Firestore

snapshot.forEach(doc => { console.log("ID: "+doc.id, '=>', "Doc DATA: "+JSON.stringify(doc.data())); }); I am looking to extract just one item from doc.data(), which is an array of strings named "supportedCurrencies". Can someone guide m ...

Is there a way to detect browser errors using JavaScript or Angular 2?

On the back-end, I am looking to add these uncaught errors to the log file. These errors are not being captured in angular2. How can I go about reading and handling these errors?https://i.sstatic.net/Kljon.png ...

Encountering issues with Node-persist on a complex Node.js application leading to missing return

I've encountered an issue with my heavy node app where I'm using node-persist to save data locally. Specifically, in a certain step of the process, I have the following code: const localdb = require('node-persist') const storage = loca ...

How do we troubleshoot the NullReferenceException thrown by async/await to determine where we went wrong?

We have recently implemented async/await in our asp.net application, and unfortunately, we are encountering a well-known exception in our live environment An unexpected error occurred, leading to the termination of the process. Application ID: /LM/W3SVC/ ...

Creating a dropdown menu in Bootstrap 5 without using any of the Bootstrap

In my Angular application, I have a header with icons and pictures that I would like to use as dropdown menus. The code snippet for this functionality is shown below: <li class="nav-item dropdown"> <a class="nav-li ...

Incorrect errors are displayed by VS Code in ts-node shell scripts

I came across an interesting article discussing running a TypeScript file on the command line, and while it seems to be functioning properly, I am encountering invalid errors in VS Code: https://i.sstatic.net/eis3X.png As seen in the terminal (bottom hal ...

The 'asObservable' property is not present on the type '() => any'.ts(2339)

Error: Property 'asObservable' does not exist on type '() => any'.ts(2339) Error: Property 'subscribe' does not exist on type 'Subscription'. Did you mean 'unsubscribe'?ts(2551) Error: Property 'sub ...

Cross-origin request error persists despite configuring headers on the server. Unable to successfully relocate image to designated directory on the server

I am encountering a CORS error specifically when sending delete requests from Angular to Laravel. Additionally, I am facing issues with moving car model images to the directory during posting, resulting in errors. I have implemented a CORS middleware and a ...

Exploring Child Types in Typescript and JSX minus the React framework

It seems like there's a missing piece of the puzzle that I can't quite figure out. Despite going through the documentation on JSX in non-React settings, I'm still unable to spot my mistake. Let's examine the following code: /** @jsx pra ...

Initial values of dual knob settings on Ionic Range and their ability to update dynamically

As someone new to using Ionic and TypeScript, I am facing challenges in setting initial values for my Ionic Range component (V5). Referring to other posts, it seems that there are upper and lower properties within ngModel, but I'm unsure about the bes ...

What is the best way to initialize elements once the data has finished loading?

I am currently working with a service class that retrieves data through HTTP in several methods. For example: filesPerWeek(login: string): Observable<FilesLastActivity[]> { return this.http.get('api/report/user_files_by_week?userId=' + ...

I rely on a powerful compiler in Angular that is only compatible with the View Engine, yet unfortunately, the View Engine is now obsolete

I recently came across this interesting update: Project is trying to disable the Ivy compiler. Angular versions 12 and above no longer support the deprecated View Engine compiler for applications. Instead, the Ivy compiler will be used for building this pr ...

`Browser Extension Compatibility``

I am currently working on developing a TypeScript extension that is compatible with all major browsers. I have come across the package https://www.npmjs.com/package/web-ext-types which I have integrated into my package.json file. While coding in TypeScrip ...

Tips on using services for storing and fetching list data in Angular

I currently have two components, the "add-expense" component and the "view-list" component. The "add-expense" component collects expense details from a form and stores them as an object. My goal is to add this object to an empty list within the "expense-li ...

Generate an interactive sitemap.xml in ReactJS for each request made to http://example.com/sitemap.xml

I am working on a single-page application (SPA) using reactjs, and I have links in the format of http://example.com/blog/:id. I want to dynamically generate a sitemap for this site. While I'm aware that there are npm packages like react-router-sitema ...

Is there a way to retrieve all potential string literals from an Array<>?

Can something similar be achieved in TypeScript? const options: Array<'Option1' | 'Option2' | 'Option3'> = []; // specify all available options: 'Option1' | 'Option2' | 'Option3' as show ...

The state of an Angular 4 component

I am currently working on an Angular 4 application that consists of two components, CompA and CompB. CompA fetches books using an http service and displays them in a table, while CompB shows static data. When navigating between these components, I notice ...

What is the best way to customize fonts for PDFMake in Angular projects?

Recently, I delved into the PDFMake documentation in hopes of creating a document for my Angular application. Along the way, I stumbled upon queries like this one, but unfortunately, found no answers. I am curious if anyone can offer insight or provide a ...