Skip to content

Commit

Permalink
fix(Transition): Do not reuse resolves for reloaded state during redi…
Browse files Browse the repository at this point in the history
…rect

closes #2539
  • Loading branch information
christopherthielen committed Mar 27, 2016
1 parent 081da32 commit 0c123c3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/state/stateObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class State {
public navigable: State;
public path: State[];
public data: any;
public includes: (name: string) => boolean;
public includes: { [name: string] : boolean };

constructor(config?: StateDeclaration) {
extend(this, config);
Expand Down
6 changes: 4 additions & 2 deletions src/transition/transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,16 @@ export class Transition implements IHookRegistry {
targetState = new TargetState(targetState.identifier(), targetState.$state(), targetState.params(), newOptions);

let redirectTo = new Transition(this._treeChanges.from, targetState, this._transitionService);
let reloadState = targetState.options().reloadState;

// If the current transition has already resolved any resolvables which are also in the redirected "to path", then
// add those resolvables to the redirected transition. Allows you to define a resolve at a parent level, wait for
// the resolve, then redirect to a child state based on the result, and not have to re-fetch the resolve.
let redirectedPath = this.treeChanges().to;
let matching: Node[] = Node.matching(redirectTo.treeChanges().to, redirectedPath);
let copyResolvesFor: Node[] = Node.matching(redirectTo.treeChanges().to, redirectedPath)
.filter(node => !reloadState || !reloadState.includes[node.state.name]);
const includeResolve = (resolve, key) => ['$stateParams', '$transition$'].indexOf(key) === -1;
matching.forEach((node, idx) => extend(node.resolves, filter(redirectedPath[idx].resolves, includeResolve)));
copyResolvesFor.forEach((node, idx) => extend(node.resolves, filter(redirectedPath[idx].resolves, includeResolve)));

return redirectTo;
}
Expand Down
47 changes: 39 additions & 8 deletions test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2095,14 +2095,21 @@ describe('otherwise and state redirects', function() {
});


describe('hook redirects from .otherwise()', function() {
var log;
describe('hook redirects', function() {
var log, resolvelog;
beforeEach(module(function ($stateProvider, $urlRouterProvider) {
log = "";
log = resolvelog = "";
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', { url: '/home', template: 'home', controller: function() { log += "homeCtrl;"; } })
.state('loginPage', { url: '/login', template: 'login' });
$stateProvider.state('home', {
url: '/home',
template: 'home <ui-view></ui-view>',
controller: function () { log += "homeCtrl;"; },
resolve: {
foo: function () { resolvelog += "fooResolve;"; return "foo"; }
}
})
.state('home.foo', {url: '/foo', template: 'foo'})
.state('loginPage', {url: '/login', template: 'login'});
}));

beforeEach(inject(function($compile, $rootScope) {
Expand All @@ -2111,7 +2118,7 @@ describe('hook redirects from .otherwise()', function() {
}));

// Test for #2455
it("should go to the redirect-to target state and url", inject(function($transitions, $q, $state, $location) {
it("from .otherwise() should go to the redirect-to target state and url", inject(function($transitions, $q, $state, $location) {
$transitions.onBefore({ to: 'home' }, function() {
return $state.target('loginPage', {}, { location: true });
});
Expand All @@ -2132,7 +2139,7 @@ describe('hook redirects from .otherwise()', function() {

$transitions.onBefore({ to: 'home' }, function($state, $transition$) {
var options = $transition$.options();
if (!options.reload && count++ < 2) {
if (!options.reload && count++ < 5) {
return $state.target($transition$.to(), $transition$.params("to"), extend({}, options, {reload: true}));
}
});
Expand All @@ -2142,4 +2149,28 @@ describe('hook redirects from .otherwise()', function() {
expect($state.current.name).toBe("home");
expect(log).toBe("homeCtrl;homeCtrl;");
}));

// Test for #2539
it("should re-resolve when reloading during a redirect", inject(function($transitions, $q, $state, $trace) {
var count = 0;
$q.flush();

expect($state.current.name).toBe("home");
expect(resolvelog).toBe("fooResolve;");

$state.go('home.foo'); $q.flush();
expect(resolvelog).toBe("fooResolve;");

$transitions.onStart({ to: 'home' }, function($transition$, $state) {
if (!$transition$.options().reload && count++ < 5) {
console.log("forcing re-enter (reload) of home state ");
var options = $transition$.options();
return $state.target($transition$.to(), $transition$.params("to"), extend({}, options, {reload: true}));
}
});

$state.go('home'); $q.flush();
expect($state.current.name).toBe("home");
expect(resolvelog).toBe("fooResolve;fooResolve;");
}));
});

0 comments on commit 0c123c3

Please sign in to comment.