Skip to content

Commit 6e5a56f

Browse files
Rafael Fernandez Serrachristopherthielen
Rafael Fernandez Serra
authored andcommitted
feat(stateService): add transition option 'supercede' so transition can be ignored if one is pending
1 parent 4a771bc commit 6e5a56f

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

src/state/stateService.ts

+4
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ export class StateService {
338338

339339
if (!ref.valid()) return <TransitionPromise>silentRejection(ref.error());
340340

341+
if (options.supercede === false && getCurrent()) {
342+
return <TransitionPromise>Rejection.ignored('Another transition is in progress and supercede has been set to false in TransitionOptions for the transition. So the transition was ignored in favour of the existing one in progress.').toPromise();
343+
}
344+
341345
/**
342346
* Special handling for Ignored, Aborted, and Redirected transitions
343347
*

src/transition/interface.ts

+12
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ export interface TransitionOptions {
7373
* You can define your own Transition Options inside this property and use them, e.g., from a Transition Hook
7474
*/
7575
custom?: any;
76+
/**
77+
* This option may be used to cancel the active transition (if one is active) in favour of the this one.
78+
* This is the default behaviour or ui-router.
79+
*
80+
*
81+
* - When `true`, the active transition will be canceled and new transition will begin.
82+
* - when `false`, the transition will be canceled if a transition is already running. This can be useful in cases where
83+
* you only want to navigate to a different state if you are not already navigating somewhere.
84+
*
85+
* @default `true`
86+
*/
87+
supercede?: boolean;
7688
/** @internalapi */
7789
reloadState?: StateObject;
7890
/** @internalapi

src/transition/transitionService.ts

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export let defaultTransOpts: TransitionOptions = {
4949
inherit: false,
5050
notify: true,
5151
reload: false,
52+
supercede: true,
5253
custom: {},
5354
current: () => null,
5455
source: 'unknown',

test/stateServiceSpec.ts

+19
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,25 @@ describe('stateService', function() {
637637
done();
638638
});
639639

640+
describe('when supercede TransitionOption is false', () => {
641+
it('ignores transition if another transition is running', async done => {
642+
$state.defaultErrorHandler(() => null);
643+
await initStateTo(A);
644+
645+
const activeTransition = $state.transitionTo(B, {});
646+
const superseded = await $state.transitionTo(C, {}, { supercede: false }).catch(err => err);
647+
648+
const result: Rejection = await superseded;
649+
expect(result.type).toEqual(RejectType.IGNORED);
650+
651+
await activeTransition;
652+
653+
expect($state.current).toBe(B);
654+
655+
done();
656+
});
657+
});
658+
640659
it('aborts pending transitions (last call wins)', async done => {
641660
$state.defaultErrorHandler(() => null);
642661
await initStateTo(A);

0 commit comments

Comments
 (0)