Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for arrayFormat: 'bracket-separator' #276

Merged
merged 16 commits into from
Mar 18, 2021

Conversation

DV8FromTheWorld
Copy link
Contributor

@DV8FromTheWorld DV8FromTheWorld commented Sep 25, 2020

The idea behind this format is to gain the advantages of short query strings that you have with comma and separator formats while marking a field as explicitly an array via a postfixed [] syntax.

import queryString from 'query-string'

queryString.stringify({ foo: ['one'] }, { arrayFormat: 'bracket-separator' })
// => foo[]=one

queryString.stringify({ foo: ['one', 'two', '', 'four' ] }, { arrayFormat: 'bracket-separator' })
// => foo[]=one,two,,four

queryString.stringify({ foo: ['one', 'two', '', 'four'] }, { arrayFormat: 'bracket-separator', arrayFormatSeparator: '|' })
// => foo[]=one|two||four

queryString.parse('?foo[]=one', { arrayFormat: 'bracket-separator' })
// => {foo: ['one']

queryString.parse('?foo[]=one,two,,four', { arrayFormat: 'bracket-separator' })
// => {foo: ['one', 'two', '', 'four']}

queryString.parse('?foo[]=one|two||four', { arrayFormat: 'bracket-separator', arrayFormatSeparator: '|' })
// => {foo: ['one', 'two', '', 'four']}

There are still are 2 question in regards to implementation:

What should happen for {foo: []}? Currently, it would drop the parameter from the stringified query which is the same as {foo: null}

This is undesirable personally. I feel like {foo: []} should produce ?foo[] unless I specify a flag to drop it.
This would be a deviation from the ?bar&biz that non-arrays get the treatment of when they are null (no trailing =), but I feel like it makes sense as we have enough information to say, explicitly, that this is an array. Whereas if it were {foo: null} we don't know, explicitly, that this is an array, so it would produce ?foo which would mean that it would roundtrip correctly.
However, the only way to produce this would be to change how the system is using Array.prototype.reduce as the reducer function is not ever invoked when the array is empty.

What should happen for {foo: ['one', null, 'three']}. Currently it will drop the null and produce foo[]=one,three

I haven't a strong opinion on this as it matches the functionality of separator. The only deviation from the separator functionality in regards to value dropping is that bracket-separator does not drop empty strings.

[Edit]: This has been changed to follow the skipNull and skipEmptyString options. As such, by default, null and '' will not be dropped. See #304 for details.
Thus, the following are true:

Input Options Output
{foo: ['one', '', null, 'four']} default settings foo[]=one,,,four
{foo: ['one', '', null, 'four']} skipNull: true foo[]=one,,four
{foo: ['one', '', null, 'four']} skipEmptyString true foo[]=one,,four
{foo: ['one', '', null, 'four']} skipEmptyString true, skipNull: true foo[]=one,four

@sindresorhus
Copy link
Owner

What should happen for {foo: []}?

?foo[] would indeed be the best output.

What should happen for {foo: ['one', null, 'three']}

I think dropping the null is the best option.

@sindresorhus
Copy link
Owner

You need to explicitly document the behavior with empty array, null in array, and empty string in array in the docs.

@sindresorhus sindresorhus changed the title Added support for arrayFormat 'bracket-separator' Add support for arrayFormat: 'bracket-separator' Dec 27, 2020
@sindresorhus
Copy link
Owner

I would also like to see more tests.

.gitignore Outdated Show resolved Hide resolved
index.d.ts Outdated Show resolved Hide resolved
index.d.ts Show resolved Hide resolved
@sindresorhus
Copy link
Owner

And sorry for the slow reply. I've just been overwhelmed with notifications.

@DV8FromTheWorld
Copy link
Contributor Author

I believe I've covered all that was asked. Please let me know if something else needs attention.
Thanks!

index.d.ts Outdated Show resolved Hide resolved
index.d.ts Outdated Show resolved Hide resolved
index.d.ts Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
Base automatically changed from master to main January 24, 2021 06:08
@sindresorhus
Copy link
Owner

Bump

@DV8FromTheWorld
Copy link
Contributor Author

DV8FromTheWorld commented Mar 10, 2021

Still have eyes on this, just haven't had a second to address. I will fix this up soon

@DV8FromTheWorld
Copy link
Contributor Author

Review comments have been addressed. Thank you for your patience.

@sindresorhus
Copy link
Owner

Can you fix the merge conflict?

index.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
@DV8FromTheWorld
Copy link
Contributor Author

DV8FromTheWorld commented Mar 17, 2021

Merge conflicts resolved.
Tests and documentation updated to reflect new skipNull and skipEmptyString changes.
PR suggestions included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants