Skip to content

Commit 000a873

Browse files
authored
Merge pull request #335 from davidtaylorhq/redirect-following-fix
Fix followRedirects when source is async and destination is sync
2 parents cea9932 + 787cfbe commit 000a873

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

lib/router/transition.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type OpaqueTransition = PublicTransition;
2828
export const STATE_SYMBOL = `__STATE__-2619860001345920-3322w3`;
2929
export const PARAMS_SYMBOL = `__PARAMS__-261986232992830203-23323`;
3030
export const QUERY_PARAMS_SYMBOL = `__QPS__-2619863929824844-32323`;
31+
export const REDIRECT_DESTINATION_SYMBOL = `__RDS__-2619863929824844-32323`;
3132

3233
/**
3334
A Transition is a thenable (a promise-like object) that represents
@@ -71,6 +72,7 @@ export default class Transition<R extends Route> implements Partial<Promise<R>>
7172
isCausedByAbortingReplaceTransition = false;
7273
_visibleQueryParams: Dict<unknown> = {};
7374
isIntermediate = false;
75+
[REDIRECT_DESTINATION_SYMBOL]?: Transition<R>;
7476

7577
/**
7678
In non-production builds, this function will return the stack that this Transition was
@@ -309,6 +311,7 @@ export default class Transition<R extends Route> implements Partial<Promise<R>>
309311
}
310312

311313
redirect(newTransition: Transition<R>) {
314+
this[REDIRECT_DESTINATION_SYMBOL] = newTransition;
312315
this.rollback();
313316
this.router.routeWillChange(newTransition);
314317
}
@@ -419,10 +422,9 @@ export default class Transition<R extends Route> implements Partial<Promise<R>>
419422
@public
420423
*/
421424
followRedirects(): Promise<R> {
422-
let router = this.router;
423-
return this.promise!.catch(function (reason) {
424-
if (router.activeTransition) {
425-
return router.activeTransition.followRedirects();
425+
return this.promise!.catch((reason) => {
426+
if (this[REDIRECT_DESTINATION_SYMBOL]) {
427+
return this[REDIRECT_DESTINATION_SYMBOL]!.followRedirects();
426428
}
427429
return Promise.reject(reason);
428430
});

tests/router_test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4743,6 +4743,35 @@ scenarios.forEach(function (scenario) {
47434743
});
47444744
});
47454745

4746+
test('Transition#followRedirects() works correctly when redirecting from an async model hook', function (assert) {
4747+
assert.expect(2);
4748+
4749+
routes.index = createHandler('index', {
4750+
beforeModel: function () {
4751+
return Promise.resolve(true).then(() => {
4752+
return router.transitionTo('about');
4753+
});
4754+
},
4755+
});
4756+
4757+
routes.about = createHandler('about', {
4758+
setup: function () {
4759+
assert.ok(true, 'about#setup was called');
4760+
},
4761+
});
4762+
4763+
router
4764+
.transitionTo('/index')
4765+
.followRedirects()
4766+
.then(function (handler: Route) {
4767+
assert.equal(
4768+
handler,
4769+
routes.about,
4770+
'followRedirects works with redirect from async hook transitions'
4771+
);
4772+
});
4773+
});
4774+
47464775
test("Returning a redirecting Transition from a model hook doesn't cause things to explode", function (assert) {
47474776
assert.expect(2);
47484777

0 commit comments

Comments
 (0)