Skip to content

Commit 1c1f91b

Browse files
committed
is() and includes() now return undefined if state does not exist, fixes #303
1 parent 4de1281 commit 1c1f91b

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

src/state.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
135135
if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {
136136
return state;
137137
}
138-
throw new Error(isStr ? "No such state '" + name + "'" : "Invalid or unregistered state");
138+
return undefined;
139139
}
140140

141141

@@ -213,9 +213,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
213213
if (!isDefined(options)) options = (options === true || options === false) ? { location: options } : {};
214214
options = extend({ location: true, inherit: false, relative: null }, options);
215215

216-
to = findState(to, options.relative);
217-
if (to['abstract']) throw new Error("Cannot transition to abstract state '" + to + "'");
218-
if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, to);
216+
var toState = findState(to, options.relative);
217+
if (!isDefined(toState)) throw new Error("No such state " + toState);
218+
if (toState['abstract']) throw new Error("Cannot transition to abstract state '" + to + "'");
219+
if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);
220+
to = toState;
219221

220222
var toPath = to.path,
221223
from = $state.$current, fromParams = $state.params, fromPath = from.path;
@@ -313,16 +315,19 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
313315
};
314316

315317
$state.is = function is(stateOrName) {
316-
return $state.$current === findState(stateOrName);
318+
var state = findState(stateOrName);
319+
return (isDefined(state)) ? $state.$current === state : undefined;
317320
};
318321

319322
$state.includes = function includes(stateOrName) {
320-
return $state.$current.includes[findState(stateOrName).name];
323+
var state = findState(stateOrName);
324+
return (isDefined(state)) ? isDefined($state.$current.includes[state.name]) : undefined;
321325
};
322326

323327
$state.href = function href(stateOrName, params, options) {
324328
options = extend({ lossy: true, inherit: false, relative: $state.$current }, options || {});
325329
var state = findState(stateOrName, options.relative);
330+
if (!isDefined(state)) return null;
326331

327332
params = inheritParams($stateParams, params || {}, $state.$current, state);
328333
var nav = (state && options.lossy) ? state.navigable : state;
@@ -332,7 +337,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
332337

333338
$state.getConfig = function (stateOrName) {
334339
var state = findState(stateOrName);
335-
return state.self || null;
340+
return (state && state.self) ? state.self : null;
336341
};
337342

338343
function resolveState(state, params, paramsAreFiltered, inherited, dst) {

test/stateSpec.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe('state', function () {
217217
}));
218218
});
219219

220-
describe('.go()', function() {
220+
describe('.go()', function () {
221221
it('transitions to a relative state', inject(function ($state, $q) {
222222
$state.transitionTo('about.person.item', { id: 5 }); $q.flush();
223223
$state.go('^.^.sidebar'); $q.flush();
@@ -266,6 +266,39 @@ describe('state', function () {
266266
}));
267267
});
268268

269+
describe('.is()', function () {
270+
it('should return true when the current state is passed', inject(function ($state, $q) {
271+
$state.transitionTo(A); $q.flush();
272+
expect($state.is(A)).toBe(true);
273+
expect($state.is('A')).toBe(true);
274+
expect($state.is(B)).toBe(false);
275+
}));
276+
277+
it('should return undefined when queried state does not exist', inject(function ($state) {
278+
expect($state.is('Z')).toBeUndefined();
279+
}));
280+
});
281+
282+
describe('.includes()', function () {
283+
it('should return true when the current state is passed', inject(function ($state, $q) {
284+
$state.transitionTo(A); $q.flush();
285+
expect($state.includes(A)).toBe(true);
286+
expect($state.includes('A')).toBe(true);
287+
expect($state.includes(B)).toBe(false);
288+
}));
289+
290+
it('should return true when the current state\'s parent is passed', inject(function ($state, $q) {
291+
$state.transitionTo('about.person.item'); $q.flush();
292+
expect($state.includes('about')).toBe(true);
293+
expect($state.includes('about.person')).toBe(true);
294+
expect($state.includes('about.sidebar')).toBe(false);
295+
}));
296+
297+
it('should return undefined when queried state does not exist', inject(function ($state) {
298+
expect($state.is('Z')).toBeUndefined();
299+
}));
300+
});
301+
269302
describe('.current', function () {
270303
it('is always defined', inject(function ($state) {
271304
expect($state.current).toBeDefined();
@@ -347,7 +380,7 @@ describe('state', function () {
347380
expect($state.getConfig('home').url).toBe('/');
348381
expect($state.getConfig('home.item').url).toBe('front/:id');
349382
expect($state.getConfig('A')).toBe(A);
350-
expect(function() { $state.getConfig('Z'); }).toThrow("No such state 'Z'");
383+
expect($state.getConfig('Z')).toBeNull();
351384
}));
352385
});
353386

0 commit comments

Comments
 (0)