With Apex calls, the method is placed into a queue that is later resolved with a Promise. To illustrate this, I wrote a simple example that demonstrates what's happening:
// We don't wait in time to get the results, so the chain fails
async function exampleThatDoesNOTWork() {
console.log('Non-working example method starts');
let value1;
let value2;
mockApexMethod1('value 1').then(
result => {
console.log('Non-working example: This will be called 3rd');
value1 = result;
});
mockApexMethod2(value1).then(
result => {
console.log('Non-working example: This will be called 4th');
value2 = result
});
console.log('Non-working example: This will be called 1st', value1);
console.log('Non-working example: This will be called 2nd', value2);
}
If you run this in a browser or even in Node, you'll see the logs occur in the order the messages indicate.
You need to wait until the first response is received before you can use that value. The original design most people figure out is to put one call inside another, which looks like this:
async function exampleThatWorks1() {
let value1;
let value2;
console.log('Working example: Nested then calls')
mockApexMethod1('value 1').then(
result1 => {
console.log('Working Example: this will be called 1st');
value1 = result1;
mockApexMethod2(value1).then(
result2 => {
console.log('Working Example: this will be called 2nd');
value2 = result2;
}
).then(() => {
console.log('Working Example: this will be called 3rd', value1);
console.log('Working Example: this will be called 4rd', value2);
})
}
)
}
This works, but becomes increasingly hard to read as you nest these calls together. Fortunately, there's a better way. You can return a Promise in a then
, and you'll be able to chain them together at the same level:
// We can chain by returning promises
async function exampleThatWorks2() {
let value1;
let value2;
mockApexMethod1('value 1').then(
(result) => {
console.log('Working Example 2: this will be called 1st');
value1 = result;
// Returning a promise allows the next "then" to read that value.
return mockApexMethod2(value1);
}
).then(
(result) => {
console.log('Working Example 2: this will be called 2nd');
value2 = result;
}
).then(
() => {
console.log('Working Example 2: this will be called 3rd', value1);
console.log('Working Example 2: this will be called 4rd', value2);
}
)
}
This works better, because we can see how the methods are being called in order. However, all of this stuff is really verbose. There's a better way to handle asynchronous calls, and that's to use await/async:
async function exampleThatWorks3() {
let value1 = await mockApexMethod1('value 1');
console.log('Working Example 3: this will be called 1st');
let value2 = await mockApexMethod2(value1);
console.log('Working Example 3: this will be called 2nd');
console.log('Working Example 3: this will be called 3rd', value1);
console.log('Working Example 3: this will be called 4rd', value2);
}
As you can see, this is really easy to read, you just need to use the await
keyword.
Demo.
IdAcc
you can access it in any method in the LWC usingthis.IdAcc
as long as the method is invoked after thecreateAcc1
imperative call has completed already.creationIBN
was called before the promise for the imperative call was finished. You need to use appropriate JavaScriptasync
andwait
or have thecreateAcc1
promise handler (thethen
block) chain the call tocreationIBN
.