Skip to content

Commit 20d6e24

Browse files
fix(UrlMatcher): Array types: Pass empty arrays through in handler
fix(UrlMatcher): Fix broken pre-replace logic Closes #2222
1 parent 2d23875 commit 20d6e24

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

src/urlMatcherFactory.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ UrlMatcher.prototype.exec = function (path, searchParams) {
261261
var param = this.params[paramName];
262262
var paramVal = m[i+1];
263263
// if the param value matches a pre-replace pair, replace the value before decoding.
264-
for (j = 0; j < param.replace; j++) {
264+
for (j = 0; j < param.replace.length; j++) {
265265
if (param.replace[j].from === paramVal) paramVal = param.replace[j].to;
266266
}
267267
if (paramVal && param.array === true) paramVal = decodePathArray(paramVal);
@@ -368,6 +368,7 @@ UrlMatcher.prototype.format = function (values) {
368368
} else {
369369
if (encoded == null || (isDefaultValue && squash !== false)) continue;
370370
if (!isArray(encoded)) encoded = [ encoded ];
371+
if (encoded.length === 0) continue;
371372
encoded = map(encoded, encodeURIComponent).join('&' + name + '=');
372373
result += (search ? '&' : '?') + (name + '=' + encoded);
373374
search = true;
@@ -532,6 +533,7 @@ Type.prototype.$asArray = function(mode, isSearch) {
532533
// Wraps type (.is/.encode/.decode) functions to operate on each value of an array
533534
function arrayHandler(callback, allTruthyMode) {
534535
return function handleArray(val) {
536+
if (isArray(val) && val.length === 0) return val;
535537
val = arrayWrap(val);
536538
var result = map(val, callback);
537539
if (allTruthyMode === true)

test/urlMatcherFactorySpec.js

+25
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ describe("UrlMatcher", function () {
272272
expect(m.exec($location.path(), $location.search())).toEqual( { param1: undefined } );
273273
$location.url("/foo?param1=bar");
274274
expect(m.exec($location.path(), $location.search())).toEqual( { param1: 'bar' } ); // auto unwrap
275+
$location.url("/foo?param1=");
276+
expect(m.exec($location.path(), $location.search())).toEqual( { param1: undefined } );
275277
$location.url("/foo?param1=bar&param1=baz");
276278
if (angular.isArray($location.search())) // conditional for angular 1.0.8
277279
expect(m.exec($location.path(), $location.search())).toEqual( { param1: ['bar', 'baz'] } );
@@ -334,6 +336,29 @@ describe("UrlMatcher", function () {
334336
expect(m.format({ "param1[]": ['bar', 'baz'] })).toBe("/foo?param1[]=bar&param1[]=baz");
335337
}));
336338

339+
// Test for issue #2222
340+
it("should return default value, if query param is missing.", inject(function($location) {
341+
var m = new UrlMatcher('/state?param1&param2&param3&param5', {
342+
params: {
343+
param1 : 'value1',
344+
param2 : {array: true, value: ['value2']},
345+
param3 : {array: true, value: []},
346+
param5 : {array: true, value: function() {return [];}}
347+
}
348+
});
349+
350+
var parsed = m.exec("/state");
351+
var expected = {
352+
"param1": 'value1',
353+
"param2": ['value2'],
354+
"param3": [],
355+
"param5": []
356+
};
357+
358+
expect(parsed).toEqualData(expected)
359+
expect(m.params.$$values(parsed)).toEqualData(expected);
360+
}));
361+
337362
it("should not be wrapped by ui-router into an array if array: false", inject(function($location) {
338363
var m = new UrlMatcher('/foo?param1', { params: { param1: { array: false } } });
339364

0 commit comments

Comments
 (0)