0

I am trying call call 2 functions one after another, if I use setTimeOut, it is working as expected. But I am trying to change the code to use the Promises. Below are parts of my code

    public getCustomFieldsData() {
        return new Promise<void>((resolve, reject) => {
          this.originalData = [];
          this.customFieldsService.getCustomFields(this.columnList, this.pageNumber, this.pageSize, null).subscribe(res => {
            if(res) {
              this.ngxSpinner.hide();          
              this.cfData = res;
              this.originalData = this.cloneData(this.cfData.customAttributes);         
              this.gridData = {
                  data: this.cfData.customAttributes,
                  total: this.cfData.totalCount
              }        
            }
          });
          resolve();
        });
    } 

    public editRows(grid) { 
          this.formGroups.markAllAsTouched(); 
          (this.formGroups.get('items') as FormArray).clear();
          let currentRow = (this.pageNumber - 1) * 20;
          let rows: any = grid.data.data;
          
          for (let i = 0; i < rows.length; i++) {
            const formGroup = this.createFormGroup(rows[i]);
            this.formGroup = formGroup;
            (this.formGroups.get('items') as FormArray).push(formGroup);        
            grid.editRow(currentRow, formGroup, {skipFocus: true});
            currentRow++;
          }
    } 

    public confirmSave(shouldSave: any, grid): void { 
      if (shouldSave == false) {
        // this.getCustomFieldsData();
        // setTimeout(() => {
          // this.editRows(grid);
        // }, 500);  
        this.getCustomFieldsData().then(res => this.editRows(grid));
      } 
    }

So, there are 3 functions and in confirmSave() function, I ma calling other two functions which should execute one after another. First I need to get the data by calling getCustomFieldsData() method, and when this functions completes its execution, then I want to call the editRows() method.

If I don't use Promise and use setTimeOut, it is working but I feel it is not consistent. So, I tried using Promise which is not working. I don't even see any errors also in the console.

Can someone please suggest if anything is wrong in the code. Thanks.

vamsi
  • 1,488
  • 3
  • 28
  • 66

2 Answers2

0

You should be resolving your Promise inside the subscription function in order to make it run properly:

public getCustomFieldsData() {
        return new Promise<void>((resolve, reject) => {
          this.originalData = [];
          this.customFieldsService.getCustomFields(this.columnList, this.pageNumber, this.pageSize, null).subscribe(res => {
            if(res) {
              this.ngxSpinner.hide();          
              this.cfData = res;
              this.originalData = this.cloneData(this.cfData.customAttributes);         
              this.gridData = {
                  data: this.cfData.customAttributes,
                  total: this.cfData.totalCount
              }        
            }
            resolve(); // <- here the data is received and fields populated
          });
       
        });
    } 

Side note, using observable pipes would make things easier.

Eldar
  • 9,781
  • 2
  • 10
  • 35
0

No need to use Promises if you already have Observables in place. Consider following code.

  public getCustomFieldsData(): Observable<any> {

    this.originalData = [];
    return this.customFieldsService.getCustomFields(this.columnList, this.pageNumber, this.pageSize, null)
      .pipe(
        tap((res) => {
          if (res) {
            this.ngxSpinner.hide();
            this.cfData = res;
            this.originalData = this.cloneData(this.cfData.customAttributes);
            this.gridData = {
              data: this.cfData.customAttributes,
              total: this.cfData.totalCount
            }
          }
        })
      );
  }

  public editRows(grid) {
    this.formGroups.markAllAsTouched();
    (this.formGroups.get('items') as FormArray).clear();
    let currentRow = (this.pageNumber - 1) * 20;
    let rows: any = grid.data.data;

    for (let i = 0; i < rows.length; i++) {
      const formGroup = this.createFormGroup(rows[i]);
      this.formGroup = formGroup;
      (this.formGroups.get('items') as FormArray).push(formGroup);
      grid.editRow(currentRow, formGroup, { skipFocus: true });
      currentRow++;
    }
  }

  public confirmSave(shouldSave: any, grid): void {
    if (shouldSave === false) {

      this.getCustomFieldsData().pipe(
        tap((grid) => {
          this.editRows(grid);
        })
      ).subscribe();
    }
  }
Lukasz Gawrys
  • 1,234
  • 2
  • 8
  • I am calling this.getCustomFieldsData(); method from several places. Can we call like this if we use Observable? – vamsi Dec 31 '21 at 09:34
  • Yes, you can call it as many times you want. Use subscribe to it each time you want to make the http request (I guess) behind it. Just make sure to manage unsubscribing properly - see e.g [this discussion](https://stackoverflow.com/questions/35042929/is-it-necessary-to-unsubscribe-from-observables-created-by-http-methods) – Lukasz Gawrys Dec 31 '21 at 09:39
  • 1
    You mean like this this.getCustomFieldsData().subscribe(); – vamsi Dec 31 '21 at 09:43