diff --git a/packages/ember-application/lib/system/application-instance.js b/packages/ember-application/lib/system/application-instance.js index 65847cd2e31..19a1a83ff61 100644 --- a/packages/ember-application/lib/system/application-instance.js +++ b/packages/ember-application/lib/system/application-instance.js @@ -241,20 +241,22 @@ const ApplicationInstance = EngineInstance.extend({ let router = get(this, 'router'); - let handleResolve = () => { - // Resolve only after rendering is complete + let handleTransitionResolve = () => { return new RSVP.Promise((resolve) => { - // TODO: why is this necessary? Shouldn't 'actions' queue be enough? - // Also, aren't proimses supposed to be async anyway? - run.next(null, resolve, this); + // Resolve once rendering is completed. `router.handleURL` returns the transition (as a thennable) + // which resolves once the transition is completed, but the transition completion only queues up + // a scheduled revalidation (into the `render` queue) in the Renderer. + // + // This uses `run.schedule('afterRender', ....)` to resolve after that rendering has completed. + run.schedule('afterRender', null, resolve, this); }); }; - let handleReject = (error) => { + let handleTransitionReject = (error) => { if (error.error) { throw error.error; } else if (error.name === 'TransitionAborted' && router.router.activeTransition) { - return router.router.activeTransition.then(handleResolve, handleReject); + return router.router.activeTransition.then(handleTransitionResolve, handleTransitionReject); } else if (error.name === 'TransitionAborted') { throw new Error(error.message); } else { @@ -268,7 +270,7 @@ const ApplicationInstance = EngineInstance.extend({ location.setURL(url); // getURL returns the set url with the rootURL stripped off - return router.handleURL(location.getURL()).then(handleResolve, handleReject); + return router.handleURL(location.getURL()).then(handleTransitionResolve, handleTransitionReject); } });