Skip to content

Commit

Permalink
Fix merging searchParams
Browse files Browse the repository at this point in the history
Fixes #1814
  • Loading branch information
szmarczak committed Jul 30, 2021
1 parent 25101f2 commit 1018c20
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion documentation/2-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ console.log(searchParams.toString());
#### **Note:**
> - `null` values are not stringified, an empty string is used instead.
> - `undefined` values are skipped.
> - `undefined` values will clear the original keys.
#### **Merge behavior:**
> - Overrides existing properties.
Expand Down
32 changes: 21 additions & 11 deletions source/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,10 @@ export default class Options {
return (this._internals.url as URL).searchParams;
}

if (this._internals.searchParams === undefined) {
this._internals.searchParams = new URLSearchParams();
}

return this._internals.searchParams;
}

Expand All @@ -1343,11 +1347,13 @@ export default class Options {
return;
}

let searchParameters = (this.searchParams ?? new URLSearchParams()) as URLSearchParams;
const searchParameters = this.searchParams as URLSearchParams;
let updated;

if (is.string(value) || (value instanceof URLSearchParams)) {
if (is.string(value)) {
updated = new URLSearchParams(value);
} else if (value instanceof URLSearchParams) {
updated = value;
} else {
validateSearchParameters(value);

Expand All @@ -1359,22 +1365,26 @@ export default class Options {

if (entry === null) {
updated.append(key, '');
} else if (entry !== undefined) {
} else if (entry === undefined) {
searchParameters.delete(key);
} else {
updated.append(key, entry as string);
}
}
}

if (this._merging) {
// eslint-disable-next-line unicorn/no-array-for-each
updated.forEach((value, key) => {
searchParameters.set(key, value);
});
} else {
searchParameters = updated;
}
// These keys will be replaced
for (const key of updated.keys()) {
searchParameters.delete(key);
}

if (!url) {
for (const [key, value] of updated) {
searchParameters.append(key, value);
}
} else if (url) {
url.search = searchParameters.toString();
} else {
this._internals.searchParams = searchParameters;
}
}
Expand Down
17 changes: 17 additions & 0 deletions test/normalize-arguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,20 @@ test('extending responseType', t => {

t.is(merged.defaults.options.responseType, 'json');
});

test('searchParams - multiple values for one key', t => {
const searchParams = new URLSearchParams();

searchParams.append('a', '100');
searchParams.append('a', '200');
searchParams.append('a', '300');

const options = new Options({
searchParams
});

t.deepEqual(
(options.searchParams as URLSearchParams).getAll('a'),
['100', '200', '300']
);
});

0 comments on commit 1018c20

Please sign in to comment.