T
TanStack3y ago
conscious-sapphire

SearchParams cannot distinguish between an array of 1 and a single primitive value

I'm not entirely sure if I misconfigured something or if the docs are outdated now, but according to https://tanstack.com/router/v1/docs/guide/search-params#json-first-search-params, JSON is supported in search parameters and is encoded into something like: /shop?pageIndex=3&includeCategories=%5B%22electronics%22%2C%22gifts%22%5D&sortBy=price&desc=true However in a sandbox I'm using to test this functionality, I'm noticing that arrays are represented as key=firstValue&key=secondValue. Calling useSearch() against this results in { key: ['firstValue', 'secondValue'] }. The issue is that if you set an array of 1, the url is in the same format as if you didn't use an array at all, thus calling useSearch results in { key: 'firstValue' } instead of { key: ['firstValue']}. This occurs using both: router.navigate({ key: ['firstValue'] }) and <Link search={{ key: ['firstValue'] }} /> Here is a code sandbox if that helps: https://codesandbox.io/s/tanstack-array-in-search-params-issue-c3nzt3?file=/src/App.js
13 Replies
other-emerald
other-emerald3y ago
Ooo you’re right I’ll fix this when I get back in front of my computer. File and issue.
conscious-sapphire
conscious-sapphireOP3y ago
GitHub
SearchParameters no longer encoded as JSON · Issue #711 · TanStack/...
Describe the bug Discussed on Discord According to https://tanstack.com/router/v1/docs/guide/search-params#json-first-search-params, JSON is supported in search parameters and is encoded into somet...
conscious-sapphire
conscious-sapphireOP3y ago
A related follow up question: Do you have any plans on supporting an integration like query-string? It would be nice to be able to choose between key[]=first&key=[]second vs key=. I'm aware there is a "Custom Search Param Serialization" page, but it seems to only apply for seralization a value to a specific key, and doesn't allow you to customize how the entirety of the search object is formatted.
other-emerald
other-emerald3y ago
I believe you can alter that as well. But I may be wrong. Router.options.parseSearch and stringifySearxh should work.
conscious-sapphire
conscious-sapphireOP3y ago
unfortunately the documentation doesn't really state what parseSearch by itself is used for (the link to it is 404), but when used in conjunction with parseSearchWith, it only allows you to modify the single value. I also noticed that if you were passing an array into navigate({search: value}), it never even calls parseSearch somehow 😅 I sorta asssumed your intention was for parseSearch to only work with primitives. let me do a little more digging and I can put together a better example for you nevermind I take it back! I looked into the source code to see what parseSearch does and figured it out. It works great with query-string. Thanks for your help!
other-emerald
other-emerald3y ago
Yep! If you can figure out how to change the default to handle this use case, I will accept a PR
conscious-sapphire
conscious-sapphireOP3y ago
I think the way you have it is fine, though I think the documentation can be improved a little. I'll type something up and open a PR for you.
conscious-sapphire
conscious-sapphireOP3y ago
https://github.com/TanStack/router/pull/712 I didn't know if you were cool with having a reference to a separate library (query-string) but I couldn't come up with an example for parseSearch and stringifySearch that didn't require writing a bunch of custom serialization code. I figured most people would probably be trying to do something like I was doing, so I just put my example in there.
GitHub
docs: Add example for parseSearch and stringifySearch by sowhatdoid...
Added an example on how to use parseSearch and stringifySearch without the parseSearchWith and stringifySearchWith utilities.
conscious-sapphire
conscious-sapphireOP3y ago
open to making any changes that you suggest though
other-emerald
other-emerald3y ago
I think we need to fix the single array item turning into a string issue.
conscious-sapphire
conscious-sapphireOP3y ago
ohh sorry, I thought you were going to look into that yourself and the pull request suggestion was for the parseSearch stuff So it seems like the problem is with the encode function in ./qss Based on your commit message, you're using a copy of https://www.npmjs.com/package/qss, which based on their examples the behavior we're seeing is expected. From what I can gather, this package doesn't support arrays of 1, and does not support nested objects. I modified the code so that it would properly match your old encoding for arrays, but I think this is going to become a thread pull to ensure nested objects as well. I'm not sure what your opinion on how the url should be structured by default is. If you're trying to base it out of the URLSearchParams standard, it doesn't support any of the above either: no nested objects, no arrays, and no differentiation between strings and numbers. if you want it to be a little more robust, you may want to consider switching from qss to a different library. As I mentioned I was using query-string, which admittedly is slower than QSS by a lot, but I'm not knowledgeable enough to know what the impact of those benchmark results would be on your product. I'm happy to work on a solution if you can give a little guidance direction wise
other-emerald
other-emerald3y ago
Fixed the default Happy to consider another one as long as it’s similar in size.
conscious-sapphire
conscious-sapphireOP3y ago
thank you!

Did you find this page helpful?