3

Is it possible to imperatively call a function from a wired function using async/await? And yes, I've seen similar questions - but they kinda miss the point I'm trying to make.

Consider this simple example:

@wire(getRecord, { recordId: '$recordId', fields: RECORD_FIELDS })
wiredRecord({ error, data }) {
    if (error) {
        console.log(error);
    } else if (data) {
        fetchMoreData({ recordId: data.fields.Id.value })
            .then((data) => {
                doStuff();
            })
            .catch((error) => {
                console.log(error);
            });
    }
}

I find this hard to read and more error-prone compared to the version using await:

@wire(getRecord, { recordId: '$recordId', fields: RECORD_FIELDS })
async wiredRecord({ error, data }) {
    if (error) {
        console.log(error);
    } else if (data) {
        try {
            const moreData = await fetchMoreData({ recordId: data.fields.Id.value });
            doStuff();
        } catch (error) {
            console.log(error);
        }
    }
}

But the second version needs async to be added to wiredRecord which a) doesn't really do anything because @wire makes this already "async" by design (as the framework calls it when needed) and b) nobody uses it. But it gets even worse if you stitch multiple calls together - it makes it even harder to read.

Is this the only way of accomplishing this? And if it is - is there a downside to it?

2 Answers 2

5

@wire doesn't make the function async. To be async means to behave like a Promise. In other words, a function marked with this keyword transforms from:

async method() {
  try {
    const result = await doSomething();
    return result;
  } catch(e) {
    handleError(e);
  }
}

to something like:

method() {
  return new Promise((resolve, reject) =>
    doSomething().then(resolve).catch((e) => {
      handleError(e);
      reject(e);
    })
  );
}

As far as making it more legible, use early returns when appliable.

@wire(getRecord, { recordId: '$recordId', fields: RECORD_FIELDS })
async wiredRecord({ error, data }) {
    if (error) {
        console.log(error);
        return null;
    }
    if(!data) {
        return null;
    }
    try {
        const moreData = await fetchMoreData({ recordId: data.fields.Id.value });
        doStuff();
    } catch (error) {
        console.log(error);
    }
}

Keep in mind that you can do multiple things in a single try-catch:

    try {
        const moreData = await fetchMoreData({ recordId: data.fields.Id.value });
        doStuff();
        const yetMoreData = await fetchEvenMoreData(params);
    } catch (error) {
        console.log(error);
    }

That's the advantage of using async over traditional promises.

2
  • Thanks! And sorry if I wasn't clear enough. I updated my answer to put the "async" in quotes with a short explanation in brackets. My question revolved more around whether I should use async for an already wired function as I see nobody using it that way.
    – Semmel
    Commented Mar 22 at 16:24
  • 1
    @Semmel It's an uncommon construction in publicly available code, I'd agree. That said, if its your project, and you have control, there's nothing wrong with using async/await.
    – sfdcfox
    Commented Mar 22 at 16:31
1

You can call another async method from the wired function by passing required parameters.

@wire(getRecord, { recordId: '$recordId', fields: RECORD_FIELDS })
wiredRecord({ error, data }) {
    if (error) {
        console.log(error);
    } else if (data) {
        this.processResponse(data.fields.Id.value)
    }
}

async processResponse(recordId){
    try {
        const moreData = await fetchMoreData({ recordId });
        //doStuff();
    } catch (error) {
        console.log(error);
    }
}
1
  • I really like this as it untangles the wiring for getRecord from processing the response which might include other calls that I can now use with await in the second function.
    – Semmel
    Commented Mar 22 at 16:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .