#searchParams to object question

1 messages · Page 1 of 1 (latest)

brave beacon
#

While doing const [searchParams, setSearchParams] = useSearchParams() I'm using setSearchParams((params) => ({ hopingToUpdateOnlyThisParams: 'foo' })) but this updates them all. I know I can't do { ...params, hopingToUpdateOnlyThisParams: 'foo' } because it's URLSearchParams. Is there a way to do this without implementing my own little transformer for URLSearchParams -> JSON. I wrote this little function (https://gist.github.com/crswll/1491dbdc465cdb85be9ec1b859f99607) but sure there's some kind of case I'm missing and google is only showing me seemingly ancient results so wondering if there's some obvious thing I'm overlooking.

#

Sidenote: Should ?a[foo]=1&b[bar]=2 be an object or is that a php convention?

clever river
brave beacon
#

Ok good, thought so but wanted to make sure I wasn't making that up.

clever river
#

the only one you get for the standard is ?a=1&a=2 becomes searchParams.getAll('a') -> [1, 2]

brave beacon
#

Ok awsome. So it literally can only be string | string[] in the end?

clever river
#

The pattern I like for this is

setSearchParams((params) => {
  params.set('foo', value)
  return params
})
clever river
brave beacon
#

Ok cool. If I'm updating searchParams though and I want to keep them all in tact I need to do something like:

setSearchParams(params => ({
  ...searchParamsToObject(params),
  expanded: toggleSearchParamsListByValue(params, 'expanded', String(category.id))
}))

this though?

clever river
brave beacon
#

I don't think I can do setSearchParams({...actualSearchParamsFromURLSearchParams}) though?

clever river
#

I don't know what that variable is

brave beacon
#

I don't think:

const updatedParams = new URLSearchParams('?a=1&b=2&c=3')
updatedParams.set('a', 'much cooler value')

setSearchParams(updatedParams)

works .

clever river
#

It should, the value you return just gets passed as an init object to a new URLSearchParams

#

I've never used it without the callback notation though

brave beacon
#

Oh... I guess I could use updateParams.toString() in that case.

clever river
#

btw you can convert to an object with Object.fromEntries(params.entries()) but you'll lose any keys with the same name

brave beacon
#

YEah that's why I have the array stuff in the code I posted.

#

Ah, you can't do params.set('param', ['1']) Seems to require a string.

#

That stinks.

#

I get it but still stinks haha.

clever river
#

Yeah you need

params.set('param', '1')
params.set('param', '2')

and on the server you can getAll('param') to get the array

#

If you want more advanced than that I'd just use a lib designed for it https://www.npmjs.com/package/qs

brave beacon
#

Sounds good. Thanks!

paper osprey
#

.set() will overwrite any existing value