Home > Blockchain >  asynchronous function doesn't work correctly
asynchronous function doesn't work correctly

Time:02-04

I have a function that displays a pop up window, the windows appears after a few seconds of delay, I found that if I remove the function this.service.GetAllItems() the windows will appear immediately, therefore I am trying to edit the function to run regardless of GetAllItems() server time response. The functions are:

    await this.service.GetAllItems(e.show).then(async Oldest => {
      this.service.GetItemId(e.showID).subscribe(x => {
        let a = x;
        this.dialog.closeAll();
        return this.dialog.open(InformationComponent, {
          data: { name: a, All: ShowAll, lang: this.TheLang }
          , panelClass: 'custom-dialog-container'
        });
      });
    });

and

  async GetAllItems(e: any) {
    try {
        const response = await this.http.get<Items[]>(this.baseUrl   'Items/GetWell='   e.toString()).toPromise();
        return response;
    } catch (err) {
        console.log(err);
    }
  }

The problem is that it simply doesn't work. Pop up will appear after a delay even though GetAllItems() is asynchronous. How can I modify the code to run asynchronously?

CodePudding user response:

It looks like the problem is caused by the fact that you are first getting all the data with GetAllItems(e.show) and inside that function you are waiting for data, since it's async the function return after few seconds because it wait for the data, and only after it opens the dialog (caused by the .then that is performed after the function is finished) The code needs some reorder of action but I can't do it right now since I'm going to sleep sorry, I think you should first open the dialog and the call GetAllItems(), I used dialogs in my project but I've never used them in a return, you can do something like this to open them before the function finishes

let dialogRef = this.dialog.open(InputDialogComponent, {
  // code
})

I don't know what you are doing inside the dialog but if you want to check for like a "cancel" button you can do something like this

dialogRef.afterClosed().subscribe(result => {
  if (result === "false") {
    return
  }
  //code
})

And this is the cancel button in the dialog

      <button  mat-dialog-close mat-dialog-close="false">Cancel</button>

The data inside the dialog should update automatically using asyncs functions

CodePudding user response:

It makes me wonder why are you using a mix of promises with observables rather than just observables? The http module returns an observable by default, and Angular along with Angular Material uses heavily observables in general.

Also, given your code example, is confusing what's the purpose of getAllItems(), that function returns a response, but you are not even using it from my perspective.

Since you need to handle multiple observables at the same time, you can make use of rxjs operators for flattening these observables such as mergeMap, switchMap, exhaustMap and concatMap depending of the situation.

Based on what you posted, try making these changes:

service

getAllItems(e: any): Observable<Items[]> {
  return this.http.get<Items[]>(this.baseUrl   'Items/GetWell='   e.toString()).pipe(
    catchError((error) => {
      console.log('Error: ', error);
      return EMPTY; // provided by RxJs
    })
  )
}
this.service.getAllItems(e.show).pipe(
  // here you are not using "oldest"... why bother then?
  mergeMap((oldest) => this.service.getItemId(e.showId).pipe(
      mergeMap(response => {
        this.dialog.closeAll();
        const data = this.getData(response);

        return this.dialog
         .open(InformationComponent, { data, panelClass: 'custom-dialog-container'})
         .afterClosed();
      })
    )
  )
).subscribe((dialogResponse) => {
   if (dialogResponse) {
     //... the dialog was closed, and you do something with the response
   }
});

private getData(name) {
  return {
    name, 
    all: showAll, 
    lang: this.theLang 
  }
}

Additionally, the naming convention for functions, variables, object properties in javascript/typescript is camelCase, don't use upper case, makes your code hard to read.

For more information about observables, take a look at the official docs

  • Related