Assume I have an LWC component and Apex Aura controller:
/* AccountController.cls */
public with sharing class AccountController {
@AuraEnabled
public static List<Account> getAll() {
try {
/* some foo logic */
return [SELECT Id, Name FROM Account];
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
}
<!--cmp.html --->
<template>
<template if:false={isLoaded}>
<lightning-spinner variant="brand" alternative-text="Loading..."></lightning-spinner>
</template>
</template>
/* cmp.js */
import { LightningElement, track } from 'lwc';
import getAll from '@salesforce/apex/AccountController.getAll';
export default class Cmp extends LightningElement {
@track isLoaded = false;
@track accounts;
@track error;
connectedCallback() {
getAll()
.then(result => {
console.log('1st then');
this.accounts = result;
/* or any other function that returns promise */
return this.promiseFunc();
})
.then(value => {
console.log('2nd then executes after 3 seconds , value: ' + value);
})
.catch(error => {
this.error = error;
})
.finally(() => {
this.isLoaded = true;
});
}
promiseFunc() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 3000);
});
}
}
This example works perfectly, but when tried to rewrite promises into async/await:
/* cmp.js */
import { LightningElement, track } from 'lwc';
import getAll from '@salesforce/apex/AccountController.getAll';
export default class Cmp extends LightningElement {
@track isLoaded = false;
@track accounts;
@track error;
connectedCallback() {
var result = await getAll();
this.accounts = result;
var value = await this.promiseFunc();
console.log('returned after 3s , value: ' + value);
this.isLoaded = true;
}
}
It throws Error
Error:(35, 15) LWC1503: Parsing error: await is a reserved word
(35:15)
But if both getAll()
and this.promiseFunc()
returns promises, why can't I await them?
Is async/await
syntax is allowed for Lightning Web Components?
If yes then how to rewrite promises into async/await
correctly and how to catch possible errors?
Best Answer
async/await
syntax is fully supported by LWC. However, as it was introduced in ES8, in old browsers, this syntax is transpiled down to ES5, which can cause performance issues if the code is executed many times.In your case to make your code deployable with using
async/await syntax
you can use 3 approaches:async init()
function and invoke it withinconnectedCallback()
hook:IIFE
:connectedCallback()
lifecycle hookasync
:I wouldn't recommend you to use the 3rd option at least for API consistency. Not sure about long term effects.
As for catching errors of async functions you can use
try/catch
block or handle them separately, usingcatch()
method because async function implicitly returns a promise: