$A.enqueueAction not being executed when using lightning out
It appears that helper.getQuoteLines(
should have a return
in front of it so that the promise chain resolves correctly. As written, getQuoteLines
will not have resolved when the following .then(
is evaluated.
Maybe it is just because there is so much of the controller code trimmed - update the question if this assumption is incorrect.
I would expect that the chain might look similar to this:
helper.getMailingPeriods(component)
.then(function (mailingPeriods) {
component.set('v.mailingPeriods', mailingPeriods);
// Get quote lines for bundle, with subquery of previously selected NTAs
return helper.getQuoteLines(component, quoteId, quoteLineId)
})
.then(function (quoteLines) {
// quotelines stuff
return resultOfQuoteLinesStuff;
})
.then(function (resultOfQuoteLines) {
// anything you needed to do with the results of the quote lines
return foo;
})
.catch(function (err) {
console.log(err);
});
Posting as an answer because I don't have the reputation to comment. Austin's answer helped to resolve this issue for me as well, and after some googling I was able to put some pieces together as to why $A.getCallback() is needed. The basic information can be found in this post:
What does $A.getCallback() actually do?
Evidently there is a "rendering cycle" where lightning rendering will occur as attributes are changed etc. This cycle is presumably started when a lightning-supported event occurs (e.g. a button click defined in the component XML). However if an event is triggered from something outside of the framework, such as a setTimeout or a promise (which is built on things like setTimeout), it will not complete. As a result, callbacks handling unsupported events need to be wrapped with $A.getCallback() to kick off a rendering cycle.
The impact of a rendering cycle appears to go beyond component rendering; in my case, as above, it prevented a server call from firing. It seems to be an overall "on" switch to the lightning framework, presumably for purposes of efficiency, though that is speculative. Best practice seems to be to always wrap promise and setTimeout callbacks with getCallback, to guarantee that the environment is "on".
As for why setTimeout and promises sometimes (often?) work without getCallback, I suspect this is happening because they are borrowing the rendering cycle of another event. When I first started seeing this issue, I was able to almost always prevent it by having a setTimeout value of 10 milliseconds, then reproduce it by using a setTimeout value of 2000 milliseconds. This behavior suggests that the rendering cycle of the code that first enqueued the timeout was still running after 10 milliseconds (but not after 2000); thus it was able to be used when the timeout completed. Depending on how long a timeout or promise takes to resolve (and how long it takes a rendering cycle to complete), the callback therefore may or may not be able to use the rendering cycle of the original code, causing intermittent results.