Skip to content

Commit df25fb5

Browse files
committed
fix(query): filter undefined values in arrays
Same behavior as with Vue Router 3
1 parent 885bb06 commit df25fb5

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

__tests__/stringifyQuery.spec.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,17 @@ describe('stringifyQuery', () => {
2828
expect(stringifyQuery({ e: undefined, b: 'a' })).toEqual('b=a')
2929
})
3030

31-
it('ignores undefined and empty arrays', () => {
32-
expect(
33-
stringifyQuery({ a: [undefined, 'b'], b: undefined, c: [] })
34-
).toEqual('a=b')
31+
it('avoids trailing &', () => {
32+
expect(stringifyQuery({ a: 'a', b: undefined })).toEqual('a=a')
33+
expect(stringifyQuery({ a: 'a', c: [] })).toEqual('a=a')
34+
})
35+
36+
it('skips undefined in arrays', () => {
37+
expect(stringifyQuery({ a: [undefined, '3'] })).toEqual('a=3')
38+
expect(stringifyQuery({ a: [1, undefined, '3'] })).toEqual('a=1&a=3')
39+
expect(stringifyQuery({ a: [1, undefined, '3', undefined] })).toEqual(
40+
'a=1&a=3'
41+
)
3542
})
3643

3744
it('stringifies arrays', () => {

src/query.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { decode, encodeQueryKey, encodeQueryValue, PLUS_RE } from './encoding'
22

33
/**
4-
* Possible values in normalized {@link LocationQuery}
4+
* Possible values in normalized {@link LocationQuery}. `null` renders the query
5+
* param but without an `=`: `?isNull&isEmpty=&other=other` -> `{ isNull: null,
6+
* isEmpty: '', other: 'other' }`.
57
*
68
* @internal
79
*/
810
export type LocationQueryValue = string | null
911
/**
10-
* Possible values when defining a query
12+
* Possible values when defining a query.
1113
*
1214
* @internal
1315
*/
@@ -93,20 +95,25 @@ export function stringifyQuery(query: LocationQueryRaw): string {
9395
key = encodeQueryKey(key)
9496
if (value == null) {
9597
// only null adds the value
96-
if (value !== undefined) search += (search.length ? '&' : '') + key
98+
if (value !== undefined) {
99+
search += (search.length ? '&' : '') + key
100+
}
97101
continue
98102
}
99103
// keep null values
100104
let values: LocationQueryValueRaw[] = Array.isArray(value)
101105
? value.map(v => v && encodeQueryValue(v))
102106
: [value && encodeQueryValue(value)]
103107

104-
for (let i = 0; i < values.length; i++) {
105-
if (values[i] === undefined) continue
106-
// only append & with non-empty search
107-
search += (search.length ? '&' : '') + key
108-
if (values[i] !== null) search += ('=' + values[i]) as string
109-
}
108+
values.forEach(value => {
109+
// skip undefined values in arrays as if they were not present
110+
// smaller code than using filter
111+
if (value !== undefined) {
112+
// only append & with non-empty search
113+
search += (search.length ? '&' : '') + key
114+
if (value != null) search += '=' + value
115+
}
116+
})
110117
}
111118

112119
return search

0 commit comments

Comments
 (0)