Skip to content

Commit 1c6220c

Browse files
fix(lazyLoad): Sync by URL after nested lazy load triggered by URL
Closes ui-router/react#7
1 parent ba67b98 commit 1c6220c

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/hooks/lazyLoadStates.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ const lazyLoadHook: TransitionHookFn = (transition: Transition) => {
2424
var toState = transition.to();
2525
let registry = transition.router.stateRegistry;
2626

27+
const transitionSource = (trans: Transition) =>
28+
trans.redirectedFrom() ? transitionSource(trans.redirectedFrom()) : trans.options().source;
29+
2730
function retryOriginalTransition() {
28-
if (transition.options().source === 'url') {
31+
if (transitionSource(transition) === 'url') {
2932
let loc = services.location, path = loc.path(), search = loc.search(), hash = loc.hash();
3033

3134
let matchState = state => [state, state.url && state.url.exec(path, search, hash)];
@@ -35,7 +38,9 @@ const lazyLoadHook: TransitionHookFn = (transition: Transition) => {
3538
let [state, params] = matches[0];
3639
return transition.router.stateService.target(state, params, transition.options());
3740
}
41+
3842
transition.router.urlRouter.sync();
43+
return;
3944
}
4045

4146
// The original transition was not triggered via url sync

test/lazyLoadSpec.ts

+52
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,58 @@ describe('a Future State', function () {
213213
})
214214
})
215215
});
216+
});
217+
218+
fdescribe('with a nested future state', () => {
219+
let count, futureStateDefA, futureStateDefB, errors;
220+
let lazyStateDefA = { name: 'A', url: '/a/:aid', params: {id: "adefault"} };
221+
let lazyStateDefB = { name: 'A.B', url: '/b/:bid', params: {id: "bdefault"} };
222+
beforeEach(() => {
223+
futureStateDefA = {
224+
name: 'A', url: '/a',
225+
lazyLoad: () => new Promise(resolve => { resolve({ states: [lazyStateDefA, futureStateDefB] }); })
226+
};
227+
228+
futureStateDefB = {
229+
name: 'A.B', url: '/b',
230+
lazyLoad: () => new Promise(resolve => { resolve({ states: [lazyStateDefB] }); })
231+
};
232+
233+
$registry.register(futureStateDefA);
234+
});
235+
236+
it('should load and activate a nested future state', (done) => {
237+
expect($state.get('A')).toBe(futureStateDefA);
238+
239+
$state.go('A.B', { aid: 'aid', bid: 'bid'}).then(() => {
240+
expect($state.current).toBe(lazyStateDefB);
241+
done();
242+
});
243+
});
244+
245+
it('should load and activate a nested future state by url sync', (done) => {
246+
services.location.setUrl('/a/aid/b/bid');
247+
$urlRouter.sync();
248+
$transitions.onSuccess({}, (trans) => {
249+
expect($state.current.name).toBe('A.B');
250+
expect($state.params).toEqualValues({ aid: 'aid', bid: 'bid' });
251+
252+
let prev1 = trans.redirectedFrom();
216253

254+
expect(prev1).toBeDefined();
255+
expect(prev1.targetState().$state().name).toBe('A.B.**');
256+
expect(prev1.options().source).toBe('redirect');
257+
258+
let prev2 = prev1.redirectedFrom();
259+
expect(prev2).toBeDefined();
260+
expect(prev2.targetState().$state().name).toBe('A.**');
261+
expect(prev2.options().source).toBe('url');
262+
263+
let prev3 = prev2.redirectedFrom();
264+
expect(prev3).toBeNull();
265+
266+
done();
267+
});
268+
});
217269
});
218270
});

0 commit comments

Comments
 (0)