-
Notifications
You must be signed in to change notification settings - Fork 139
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
URLSearchParams delete all vs delete one #335
Comments
I think I'd go with a second optional parameter (option 1). The |
Very fair. While I would personally still lean |
Just making sure, if there are multiple pairs with same name and value, all of such pairs will be deleted by the two-parameter variant, right? |
Correct. See the last example in the first post. Additionally, I can't think of a case where only a subset would need to be deleted, so I don't think we need to consider a way to do that. If someone is considering the multiplicity of the pair, I would recommend instead passing an additional key-value pair with the count. |
Sorry, I missed that in my first reading. The idea SGTM. If people really want to do more advanced manipulations, there's always |
Any update? |
What would help in driving this forward is some indication that this is a common need (e.g., StackOverflow questions) and is being addressed in libraries (with the proposed semantics). That might make this a more compelling case to implementers. |
Just ran into this myself. I guessed that Use case is a typical sidebar product search filters. If you've got links to multiple brands of shoes maybe you'd like to click the brand to append it to the search params, and if it's already there, remove it. Of course you can make an array, manipulate it, and construct a new one, but |
I still don't think anybody has answered Anne's question, and unfortunately I didn't see any libraries or polyfills where this is implemented. Re: the API design discussion upthread, I thought this analogous data structure could be a good place to start, since AFAICT it's basically the same thing. To save you a click, their answer is, |
This issue now has 30 upvotes and 1 downvote, which would seem to be an "indication of common need". I think it's worth doing some work to investigate how feasible "option 1" is (provide an optional second parameter). If there's a lot of existing code that's passing a second parameter to |
I'm not sure the correct way to give an "indication of common need" but I would like to add my voice to those expecting To give a concrete use case: A query string containing filters that can have multiple. Such as But when wanting to delete a filter, it seems over the top to need to manipulate the array to rebuild the query just to delete one of the options. For anyone finding this like I did via Google, here's how I handled the lack of this feature:
|
Now 50 upvotes. This would be realy handy feature :) |
When using @ShaneHudson's solution, be aware that Here's a version which avoids this pitfall:
Another difference is that this version will delete all entries which match the given |
Today I discovered you can have multiple params with the same key. Today it popped up in my twitter time line: post from Ryan Florence and reply from Jake Archibald linking to an article. Yes, we need this feature. |
If we do this we should also change Since my last comment here I'm glad to see @thw0rted's comment about precedence in other code. I think ideally we have some more of that to ensure we're doing the right thing. @valenting @domenic @tabatkins thoughts on adding this? |
Just to look for some more precedent:
This is just me looking at the first two pages of Google results, so I think it's fairly well established that "remove one k/v pair" is a reasonable part of a multimap API. Re: whether it removes a single matching k/v pair or all matching pairs, I can see arguments either way, but I lean towards just removing one. (Specifically the first or last.) Most of the time it won't matter because you won't have dupes anyway, but sometimes you have dupes quite purposely and we can't reasonably guess whether someone wants to remove all of them or just one. If we went with "remove all" then the people wanting "remove one" behavior would have to do essentially the same workarounds as shown in this thread, while if we went with "remove one" then people wanting to remove all would have a much easier "remove in a while loop" workaround. (Ugh, the lack of a 2-arg has() method means they'd have to do |
Would there be no scope to pass an argument for removing all matching pairs with the default being singular (or vice versa)? I definitely think tbh the most common situation is that if someone has tried to remove a pair, they will expect the result to not have the pair.
…On 23 Nov 2022, 4:53 PM +0000, whatwg/url ***@***.***>, wrote:
whether it removes a single matching k/v pair or all matching pairs, I can see arguments either way, but I lean towards just removing one
|
I don't think there's a clear "most common" situation. For example, if you're using PHP it's common to have several inputs named |
I think every use case presented could be addressed with clean ergonomics, without changing the meaning of any current methods, by adding:
|
I created a polyfill to add support for |
I like the idea of overloading It sounds like there's three different use cases for deleting by key and value:
My inclination based on this analysis would be to go with removal all semantics for (HTTP headers are represented by |
I'm trying to consider this in light of what an eventual JS multimap might look like too, so I'm assuming all use-cases are valid a priori right now. My issue here is that the existing methods that duplicate Map methods all treat it like a normal Map, with a single value per key, while the methods that recognize this as a multimap all treat it like an ordered list of arbitrary values per key. If calling |
We do that for the keys as well so I don't see why we wouldn't do the same for the values. If you really want delete-a-single-entry semantics it probably makes more sense to pass an index. |
Apologies, I'm not sure what you mean by "we do that for the keys". |
You can have multiple entries with the same key and all will be deleted. |
I agree. I would aim for consistency with the existing behavior of
const params = new URLSearchParams('foo=1&foo=2&bar=3&bar=3');
params.delete('foo');
params.toString(); // 'bar=3&bar=3'
const params = new URLSearchParams('foo=1&foo=2&bar=3&bar=3');
params.delete('bar', '3');
params.toString(); // 'foo=1&foo=2' |
I agree, and you still have the ability to manipulate the array directly like we do currently in the case of wanting a specific one deleted.
…On 1 Dec 2022 at 10:17 AM +0000, Martin ***@***.***>, wrote:
I agree. I would aim for consistency with the existing behavior of URLSearchParams functions.
URLSearchParams.delete(key) deletes all entries with matching key
const params = new URLSearchParams('foo=1&foo=2&bar=3&bar=3');
params.delete('foo');
params.toString(); // 'bar=3&bar=3'
URLSearchParams.delete(key, value) deletes all entries with matching key and value
const params = new URLSearchParams('foo=1&foo=2&bar=3&bar=3');
params.delete('bar', '3');
params.toString(); // 'foo=1&foo=2'
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Right, because you're calling .delete(key), which it inherits from masquerading as a Map; under the model that those methods act under, each key is unique among the k/v pairs, so deleting the key needs to ensure that afterwards the key is not present in the map. Essentially it just pretends that all subsequent k/v pairs with a repeated key don't exist, and ensures that the results after calling the methods accord with that - returning only the first from .get(), replacing all of them with .set(), deleting all of them with .delete(). But for the methods that aren't borrowed from Map (append, getAll), they use the mental model of a list of arbitrary k/v pairs, where none of the keys, values, or k/v pairs are necessarily unique. It would be odd if the 2-arg delete method operated under a third model, where the keys and values aren't unique but the k/v pairs are. |
I'm not sure it's that weird, as unlike |
Just commenting that I'm hand rolling an implementation and that several of the proposed solutions above are satisfactory improvements for workflows that involve toggling key/value pairs. |
Also add <div algorithm> wrappers. Tests: web-platform-tests/wpt#39865. Fixes #335.
The specification for URLSearchParams currently reads that delete should delete all pairs that have the supplied key. I think the ability to delete a specific key value pair should be added.
For example:
A use case for this is faceted searching. Say the user has selected three keys to facet with. Example url:
http://example.com/?q=searchTerms&facet.category=selection1&facet.category=selection2&facet.category=selection3
. Now the user wants to clear only selection2 from their search.While it wouldn't be too difficult to use the current methods to obtain the desired output above (getAll the given key, delete all pairs with the given key, iterate over the getAll result adding back everything but the one pair), I think it goes against the goal of the URLSearchParams class as I understand it. It seems URLSearchParams tries to abstract away the string filtering and concatenations that were required for query params before. The workaround falls back into that extra manipulation approach.
I think that any of the following changes would solve this.
Example: See above.
For both options, in cases where there are repeats of the same key-value pair, all instances would be deleted.
Example:
While I am more of a fan of option 2 because it lines up closer to the get/getAll methods, it requires a backwards incompatible change. Therefore, it would probably be best to go the route of option 1. (Arguably, a third option could be to keep 1 argument delete the same, introduce deleteAll and two argument delete, but is probably extra and unnecessary.)
What are other people's thoughts?
The text was updated successfully, but these errors were encountered: