Skip to content

Commit a479fbd

Browse files
fix($urlMatcherFactory): fix mixed path/query params ordering problem
If a state defined a query param and a substate defined a path param, the URLs were generated and matched in the wrong order. A substate creates its UrlMatcher using .concat() and a concat()'d UrlMatcher assumed the parent params order mattered. Switched to populating an array of params in the order they were parsed in UrlMatcher constructor. Closes #1543
1 parent 5e6783b commit a479fbd

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

src/urlMatcherFactory.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ function UrlMatcher(pattern, config, parentMatcher) {
8686
compiled = '^', last = 0, m,
8787
segments = this.segments = [],
8888
parentParams = parentMatcher ? parentMatcher.params : {},
89-
params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet();
89+
params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet(),
90+
paramNames = [];
9091

9192
function addParameter(id, type, config, location) {
93+
paramNames.push(id);
9294
if (parentParams[id]) return parentParams[id];
9395
if (!/^\w+(-+\w+)*(?:\[\])?$/.test(id)) throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
9496
if (params[id]) throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
@@ -162,6 +164,7 @@ function UrlMatcher(pattern, config, parentMatcher) {
162164

163165
this.regexp = new RegExp(compiled, config.caseInsensitive ? 'i' : undefined);
164166
this.prefix = segments[0];
167+
this.$$paramNames = paramNames;
165168
}
166169

167170
/**
@@ -277,7 +280,7 @@ UrlMatcher.prototype.exec = function (path, searchParams) {
277280
* pattern has no parameters, an empty array is returned.
278281
*/
279282
UrlMatcher.prototype.parameters = function (param) {
280-
if (!isDefined(param)) return this.params.$$keys();
283+
if (!isDefined(param)) return this.$$paramNames;
281284
return this.params[param] || null;
282285
};
283286

@@ -499,7 +502,7 @@ Type.prototype.$asArray = function(mode, isSearch) {
499502
};
500503
}
501504

502-
function toArray(val) { return isArray(val) ? val : [ val ] }
505+
function toArray(val) { return isArray(val) ? val : [ val ]; }
503506
function fromArray(val) { return mode === "auto" && val && val.length === 1 ? val[0] : val; }
504507
function falsey(val) { return !val; }
505508

test/urlMatcherFactorySpec.js

+6
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ describe("UrlMatcher", function () {
178178
expect(m.exec("/foo")).toEqual({});
179179
expect(m.exec("/FOO")).toEqual({});
180180
});
181+
182+
it("should generate/match params in the proper order", function() {
183+
var m = new UrlMatcher('/foo?queryparam');
184+
m = m.concat("/bar/:pathparam");
185+
expect(m.exec("/foo/bar/pathval", { queryparam: "queryval" })).toEqual({ pathparam: "pathval", queryparam: "queryval"});
186+
});
181187
});
182188

183189

0 commit comments

Comments
 (0)