fix: multi valued query variables did not work correctly, fixes #10539

This commit is contained in:
Torkel Ödegaard
2018-01-17 09:41:06 +01:00
parent c4c0e7934b
commit 66edb29f53
4 changed files with 84 additions and 12 deletions

View File

@@ -0,0 +1,52 @@
/**
* @preserve jquery-param (c) 2015 KNOWLEDGECODE | MIT
*/
export function toUrlParams(a) {
let s = [];
let rbracket = /\[\]$/;
let isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
let add = function(k, v) {
v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v;
s[s.length] = encodeURIComponent(k) + '=' + encodeURIComponent(v);
};
let buildParams = function(prefix, obj) {
var i, len, key;
if (prefix) {
if (isArray(obj)) {
for (i = 0, len = obj.length; i < len; i++) {
if (rbracket.test(prefix)) {
add(prefix, obj[i]);
} else {
buildParams(prefix, obj[i]);
}
}
} else if (obj && String(obj) === '[object Object]') {
for (key in obj) {
buildParams(prefix + '[' + key + ']', obj[key]);
}
} else {
add(prefix, obj);
}
} else if (isArray(obj)) {
for (i = 0, len = obj.length; i < len; i++) {
add(obj[i].name, obj[i].value);
}
} else {
for (key in obj) {
buildParams(key, obj[key]);
}
}
return s;
};
return buildParams('', a)
.join('&')
.replace(/%20/g, '+');
}

View File

@@ -0,0 +1,26 @@
import { ViewStore } from './ViewStore';
import { toJS } from 'mobx';
describe('ViewStore', () => {
let store;
beforeAll(() => {
store = ViewStore.create({
path: '',
query: {},
});
});
it('Can update path and query', () => {
store.updatePathAndQuery('/hello', { key: 1, otherParam: 'asd' });
expect(store.path).toBe('/hello');
expect(store.query.get('key')).toBe(1);
expect(store.currentUrl).toBe('/hello?key=1&otherParam=asd');
});
it('Query can contain arrays', () => {
store.updatePathAndQuery('/hello', { values: ['A', 'B'] });
expect(store.query.get('values').toJS()).toMatchObject(['A', 'B']);
expect(store.currentUrl).toBe('/hello?values=A&values=B');
});
});

View File

@@ -1,15 +1,9 @@
import { types } from 'mobx-state-tree';
import { toJS } from 'mobx';
import { toUrlParams } from 'app/core/utils/url';
const QueryValueType = types.union(types.string, types.boolean, types.number);
const urlParameterize = queryObj => {
const keys = Object.keys(queryObj);
const newQuery = keys.reduce((acc: string, key: string, idx: number) => {
const preChar = idx === 0 ? '?' : '&';
return acc + preChar + key + '=' + queryObj[key];
}, '');
return newQuery;
};
const QueryInnerValueType = types.union(types.string, types.boolean, types.number);
const QueryValueType = types.union(QueryInnerValueType, types.array(QueryInnerValueType));
export const ViewStore = types
.model({
@@ -21,7 +15,7 @@ export const ViewStore = types
let path = self.path;
if (self.query.size) {
path += urlParameterize(self.query.toJS());
path += '?' + toUrlParams(toJS(self.query));
}
return path;
},