Skip to content

Commit b027375

Browse files
committed
Merge pull request #138 from nateabele/master
Method for generating URLs from states
2 parents 4f8f5ab + ddbef65 commit b027375

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

src/state.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
184184
}
185185

186186
// Normalize/filter parameters before we pass them to event handlers etc.
187-
var normalizedToParams = {};
188-
forEach(to.params, function (name) {
189-
var value = toParams[name];
190-
normalizedToParams[name] = (value != null) ? String(value) : null;
191-
});
192-
toParams = normalizedToParams;
187+
toParams = normalize(to.params, toParams || {});
193188

194189
// Broadcast start event and cancel the transition if requested
195190
if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams)
@@ -271,6 +266,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
271266
return $state.$current.includes[findState(stateOrName).name];
272267
};
273268

269+
$state.href = function (stateOrName, params) {
270+
var state = findState(stateOrName), nav = state.navigable;
271+
if (!nav) throw new Error("State '" + state + "' is not navigable");
272+
return nav.url.format(normalize(state.params, params || {}));
273+
};
274274

275275
function resolveState(state, params, paramsAreFiltered, inherited, dst) {
276276
// We need to track all the promises generated during the resolution process.
@@ -345,6 +345,16 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
345345
});
346346
}
347347

348+
function normalize(keys, values) {
349+
var normalized = {};
350+
351+
forEach(keys, function (name) {
352+
var value = values[name];
353+
normalized[name] = (value != null) ? String(value) : null;
354+
});
355+
return normalized;
356+
}
357+
348358
function equalForKeys(a, b, keys) {
349359
for (var i=0; i<keys.length; i++) {
350360
var k = keys[i];

test/stateSpec.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ describe('state', function () {
3232
.state('C', C)
3333
.state('D', D)
3434
.state('DD', DD)
35-
.state('E', E);
35+
.state('E', E)
36+
37+
.state('home', { url: "/" })
38+
.state('home.item', { url: "front/:id" })
39+
.state('about', { url: "/about" })
40+
.state('about.person', { url: "/:person" })
41+
.state('about.person.item', { url: "/:id" });
3642

3743
$provide.value('AppInjectable', AppInjectable);
3844
}));
@@ -226,7 +232,7 @@ describe('state', function () {
226232
}));
227233
});
228234

229-
235+
230236
describe('.transition', function () {
231237
it('is null when no transition is taking place', inject(function ($state, $q) {
232238
expect($state.transition).toBeNull();
@@ -240,4 +246,22 @@ describe('state', function () {
240246
expect($state.transition).toBe(trans);
241247
}));
242248
});
249+
250+
251+
describe('.href()', function () {
252+
it('aborts on un-navigable states', inject(function ($state) {
253+
expect(function() { $state.href("A"); }).toThrow("State 'A' is not navigable");
254+
}));
255+
256+
it('generates a URL without parameters', inject(function ($state) {
257+
expect($state.href("home")).toEqual("/");
258+
expect($state.href("about", {})).toEqual("/about");
259+
expect($state.href("about", { foo: "bar" })).toEqual("/about");
260+
}));
261+
262+
it('generates a URL with parameters', inject(function ($state) {
263+
expect($state.href("about.person", { person: "bob" })).toEqual("/about/bob");
264+
expect($state.href("about.person.item", { person: "bob", id: null })).toEqual("/about/bob/");
265+
}));
266+
});
243267
});

0 commit comments

Comments
 (0)