S
SolidJS12mo ago
Khyonn

Troubles Reading / Writing search params using solid-router useSearchParams()

Hello, I have some trouble reading/writing an array of search params using solid-router/useSearchParams() primitive
// for an URL like ?plop=a&plop=b
function MyComponent () {
const [searchParams, setSearchParams] = useSearchParams()
console.log(searchParams.plop) // 'b' when I wanted ['a', 'b']
return (
<button
onClick={() => {
setSearchParams({ pouet: ['a', 'b'] }) // update params like ?plop=a&plop=b&pouet=a%2Cb when I wanted ?plop=a&plop=b&pouet=a&pouet=b
}}>
Update search params
</button>
}
// for an URL like ?plop=a&plop=b
function MyComponent () {
const [searchParams, setSearchParams] = useSearchParams()
console.log(searchParams.plop) // 'b' when I wanted ['a', 'b']
return (
<button
onClick={() => {
setSearchParams({ pouet: ['a', 'b'] }) // update params like ?plop=a&plop=b&pouet=a%2Cb when I wanted ?plop=a&plop=b&pouet=a&pouet=b
}}>
Update search params
</button>
}
Do you have any tips to make it work ?
4 Replies
Alex Lohr
Alex Lohr12mo ago
Setting the same parameter twice is not supported at the moment
Khyonn
Khyonn12mo ago
Ok, so the best way to do it currently would be to serialize / deserialize manually like so ?
const serializeParams = (params = {}, joinChar = '|') => {
return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, Array.isArray(value) ? value.join(joinChar) : value]))
}
const deserializeParams = (params = {}, joinChar = '|') => {
return Object.fromEntries(
Object.entries(params)
.map(([key, value]) => [key, value.includes(joinChar) ? value.split(joinChar) : value])
)
)
}

// for an URL like ?plop=a|b or ?plop=a%7Cb
function MyComponent () {
const [searchParams, setSearchParams] = useSearchParams()
console.log(deserializeParams(searchParams).plop) // ['a', 'b']
return (
<button
onClick={() => {
setSearchParams(serializeParams({ pouet: ['a', 'b'] })) // will update params like ?plop=a%7Cb&pouet=a%7Cb
}}>
Update search params
</button>
}
const serializeParams = (params = {}, joinChar = '|') => {
return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, Array.isArray(value) ? value.join(joinChar) : value]))
}
const deserializeParams = (params = {}, joinChar = '|') => {
return Object.fromEntries(
Object.entries(params)
.map(([key, value]) => [key, value.includes(joinChar) ? value.split(joinChar) : value])
)
)
}

// for an URL like ?plop=a|b or ?plop=a%7Cb
function MyComponent () {
const [searchParams, setSearchParams] = useSearchParams()
console.log(deserializeParams(searchParams).plop) // ['a', 'b']
return (
<button
onClick={() => {
setSearchParams(serializeParams({ pouet: ['a', 'b'] })) // will update params like ?plop=a%7Cb&pouet=a%7Cb
}}>
Update search params
</button>
}
Alex Lohr
Alex Lohr12mo ago
yes.
mdynnl
mdynnl12mo ago
i wonder why searchParams isn't exposed you could still use a new instance for de/se though