LWC NavigationMixin.Navigate – Issue with Getting ID After Creating New Record

In my LWC I create a new record, and after this want to navigate to the new record to allow the user to enter some required info. What I'm finding though, is although my navigate statement is after the create call (it calls a method to do the create), it runs the navigate before it's done the create.

Do I need to have some sort of pause in between calling the create method before the navigate?

    this.createCertificate();
    console.log(
      "After create, back in calling method - certificate Id + Name : " +
        this.certid +
        " " +
        this.certref
    );
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: this.certid,
        actionName: "edit"
      }
    });

  createCertificate() {
    const fields = {};
    fields[RECTYPE_FIELD.fieldApiName] = this.recordTypeId;
    fields[ACCOUNT_FIELD.fieldApiName] = this.aid;
    fields[STATUS_FIELD.fieldApiName] = this.status;
    fields[CERTTYPE_FIELD.fieldApiName] = this.certtype;
    console.log("certificate fields : " + fields);
    const recordInput = { apiName: CERTIFICATE_OBJECT.objectApiName, fields };
    createRecord(recordInput)
      .then(cert => {
        const retCert = JSON.parse(JSON.stringify(cert));
        this.certref = retCert.fields.Name.value;
        this.certid = cert.id;
        console.log(
          "certificate Id + Name : " + this.certid + " " + this.certref
        );
        this.dispatchEvent(
          new ShowToastEvent({
            title: "Success",
            message: "Certificate created - Ref No: " + this.certref,
            variant: "success"
          })
        );

        if (this.isBio) {
          sendEmail({ cEmail: this.aemail, cId: this.certid, accId: this.aid })
            .then(result => {
              this.dispatchEvent(
                new ShowToastEvent({
                  title: "Success",
                  message: "Email has been sent",
                  variant: "success"
                })
              );
            })
            .catch(error => {
              this.dispatchEvent(
                new ShowToastEvent({
                  title: "Error on send",
                  message: error.message.body,
                  variant: "error"
                })
              );
            });
        }
      })
      .catch(error => {
        this.dispatchEvent(
          new ShowToastEvent({
            title: "Error creating record",
            message: error.body.message,
            variant: "error"
          })
        );
      });
  }

I also added 2 console.log statements – one in the createCertificate method, which, as the image below shows, displays after the one in the code snippet above, which I find confusing. I would expect the createCertificate method to run and complete before it moves to the next line of code. How do I get it to do so?

enter image description here

Best Answer

when createCertificate() is invokes, it invoked async method createRecord(recordInput) - but before it returns the result from server, the lines after that will be executed in synchronous way. You need fire navigation after the result is returned in then as below: (and remove navigation from top)

createRecord(recordInput)
  .then(cert => {
      .......
      this[NavigationMixin.Navigate]({
        type: "standard__recordPage",
        attributes: {
            recordId: this. cert.Id,
            actionName: "edit"
        }
        });
}

Option 2:

You can use async-await function.

async firstMethod() {
    ...
    const cert = await this.createCertificate();
    
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: this.cert.Id,
        actionName: "edit"
      }
    });
}

and return new Promise in createCertificate() as shown in async-await function

Related Topic