Felix
Felix

Reputation: 5619

JavaScript how to wait until a function and all its child functions are done

In my reactJS application I have the following button with an onClick

<Button
  onClick={() => {
    this.authenticateUser(this.state.user, this.state.password)
      .then(user => {
        if (user === "true") {
          this.setState({ markAsDone: true }, () => {
            this.startStepInstancePostConditions(this.props.step, this.props.instance.id);
            this.markSepInstanceAsDone(this.props.step, this.props.instance.id);
          });
          this.toggleDialog();
        }
      })
      .catch(() => {
        this.snackBarHandler(this.toggleSnackBar, "", t("auditLogs:newAuditLog.error"), 5000);
      });
  }}
>
  {t("processes:processStepInstances.markAsDoneDialog.save")}
</Button>

I'm not sure how to solve my problem.

the two functions:

this.startStepInstancePostConditions(this.props.step,this.props.instance.id);  

this.markSepInstanceAsDone(this.props.step,this.props.instance.id);

iterates over some arrays and do some axios posts.

I want that my application calls this:

 this.props.history.push("/processes/processInstance/" + this.props.instance.id);

if the above two functions and all theri child functions are done. how can I achive this?

Thanks in advance

Update:

export function markSepInstanceAsDone(step, processInstanceId) {
    const user = sessionStorage.getItem("username");
    const clientId = sessionStorage.getItem("client");
    axios.post(PROCESS_INSTANCES_URL + '/markProcessStepInstanceAsDone/' + clientId, {
        stepInstanceId: step.id,
        user: user,
        comment: this.state.markStepInstanceAsDoneComment
    })
        .then((response) => {
            this.getContentComponentPostConditions(step, processInstanceId);
            this.props.history.push("/processes/processInstance/" + processInstanceId);
        })
        .catch((error) => {
            this.setState({dialogLoaded: false});
            console.log(error);
        });
}

Update

export function startStepInstancePostConditions(step,processInstanceID) {
    step.postConditions.map(postConditionTemplate => {
        axios.get(API_URL + '/processStepTemplates/' + postConditionTemplate.id)
            .then(response => {
                this.createProcessInstanceAutomatic(postConditionTemplate, response.data);
            })
            .catch(error => {
                console.log(error);
            });
    });
}

Upvotes: 3

Views: 85

Answers (1)

kingdaro
kingdaro

Reputation: 12008

Have both of your functions return the promises from their axios calls, then you can use Promise.all to wait until both of them are done, and do something afterward.

startStepInstancePostConditions() {
  return axios.post('...')
}
markSepInstanceAsDone() {
  return axios.post('...')
}

// inside the authenticateUser callback
Promise.all([
  this.startStepInstancePostConditions(this.props.step, this.props.instance.id),
  this.markSepInstanceAsDone(this.props.step, this.props.instance.id)
]).then(() => {
  this.props.history.push("/processes/processInstance/" + this.props.instance.id)
})

Upvotes: 3

Related Questions