'Show alert when subscribe ends

I'm needing some help...

There are two endpoints.

  • updateVariable (to update every variable modified, could be 2 or more).
  • updateDocument (to update document, this happens once).

I need to update the document after to update all the variables available. This is my code, and it works, but it's slow. It's waiting to finish to update one variable to go for the next. I know with a mergeMap I could update all the variables at the same time, but I don't know what is the best way to implement it.

  async onClickUpdateForm() {
    let variables = this.componenList.getForm;

    for await (let x of this.documentContent.variables) {
      var var_id: string = x._id;
      
      var category = variables.find((e) => e.category == x.category.name);
      
      // *THIS IS JUST ELEMENTS TO ADD IN THE OBJECT TO SEND*
      var element = category.parameters.find(
        (e: { name: any }) => e.name == x.name
      );

      if (!x.isAConditional) {
        var dataToSend = {
          isAConditional: x.isAConditional,
          name: element.name,
          label: element.label,
          description: x.description,
          type: element.type,
          values: element.values,
          html_content: x.html_content,
          position: x.position,
          quantity: x.quantity,
          placeholder: element.placeholder,
          isRequired: element.isRequired,
        };
      } else {
        var dataToSend = {
          isAConditional: x.isAConditional,
          name: x.name,
          label: x.label,
          description: x.description,
          type: x.type,
          values: x.values,
          html_content: x.html_content,
          position: x.position,
          quantity: x.quantity,
          isRequired: x.isRequired,
          placeholder: x.placeholder,
        };
      }

      // *UPDATING VARIABLE*
      await this._documentService
        .updateVariable(dataToSend, this.documentId, var_id)
        .pipe(take(1))
        .toPromise()
        .then((x) => {
          console.log(x);
        });
    }

    let dataToUpdate: any = {
      name: this.nameForm,
      description: this.descriptionForm,
      owner: this.userId,
      status_doc: 'EDIT_FORM',
    };

    // *UPDATING DOCUMENT*
    this._documentService
      .updateDocument(dataToUpdate, this.documentId)
      .pipe(take(1))
      .subscribe((x) => {
        console.log(x);
        this._messageService.add({
          severity: 'success',
          summary: 'Updated',
          detail: 'The form was updated.',
        });
      });
  }

Thank you all!



Solution 1:[1]

By the looks of it you have two independent observables sources. To process one and when that finishes process the other one, you can use concat(obs1, obs2).

It would be something like this.

onClickUpdateForm() {
  let variables = this.componenList.getForm;
  let dataToUpdate: any = {
    name: this.nameForm,
    description: this.descriptionForm,
    owner: this.userId,
    status_doc: 'EDIT_FORM',
  };
  
  concat(
    from(this.documentContent.variables).pipe(
      mergeMap(x => {
        ... // <-- all your mapping
        return this._documentService.updateVariable(dataToSend, this.documentId, var_id)  
      });
    ),
    this._documentService.updateDocument(dataToUpdate, this.documentId)
  ).pipe(
    tap({
      complete: () => {
        this._messageService.add({
          severity: 'success',
          summary: 'Updated',
          detail: 'The form was updated.',
        });
      }
    })
  ).subscribe()
}   

Cheers

Solution 2:[2]

You can use Promise.all in JS, that is waiting for all promises to be resolved. For example:

async onClickUpdateForm() {
    let variables = this.componenList.getForm;

    // ---> Wait for all promises to be resolved
    await Promise.all(this.documentContent.variables.map((x) => {
      var var_id: string = x._id;
      
      // your logic here...

      // *UPDATING VARIABLE*
      return this._documentService
        .updateVariable(dataToSend, this.documentId, var_id)
        .pipe(take(1))
        .toPromise();
    }));

    let dataToUpdate: any = {
      name: this.nameForm,
      description: this.descriptionForm,
      owner: this.userId,
      status_doc: 'EDIT_FORM',
    };

    // *UPDATING DOCUMENT*
    this._documentService
      .updateDocument(dataToUpdate, this.documentId)
      .pipe(take(1))
      .subscribe((x) => {
        console.log(x);
        this._messageService.add({
          severity: 'success',
          summary: 'Updated',
          detail: 'The form was updated.',
        });
      });
  }

More info here: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 pierreavn