1

I'm migrating from vanilla React to NextJS. Before the change, I got my URL query params (the part after the ? in the URL) through react-router's useSearchParams hook, which returns URLSearchParams.

NextJS's router, however, returns the query params in the form of ParsedUrlQuery. I want to forward these ParsedUrlQuery parameters to my (Express) backend server, again in the form of URL query params (the same form they are shown in the website's URL) but I can't figure out how to URL-encode them.

Here is my old code. I need to replace URLSearchParams for ParsedUrlQuery. Or alternatively, transform the ParsedUrlQuery into URLSearchParams How can I do that?

export async function searchResources(searchParams: URLSearchParams): Promise<SearchResourcesResponse> {
    const response = await fetchWithTimeout(
        process.env.NEXT_PUBLIC_TUTHUB_SERVER_URL + '/resources?' + searchParams
    )
    const resources = await response.json();
    return resources;
};
Florian Walther
  • 6,237
  • 5
  • 46
  • 104

1 Answers1

3

EDIT

Simplest method: use the the encode/stringify method included in the querystring lib

import { encode } from 'querystring'

// From useRouter:
// const { query } = useRouter()

// From GetServerSidePropContext
// const { query } = ctx

const urlQueryString = encode(query)
const searchParams = new URLSearchParams(urlQueryString )

OLD ANSWER

Or you can use these helper methods to transform the query params from one type to another in a very simple way.

export function parsedUrlQueryToURLSearchParams(
  query: ParsedUrlQuery
): URLSearchParams {
  const searchParams = new URLSearchParams()
  for (const [key, value] of Object.entries(query)) {
    if (!value) continue
    if (Array.isArray(value)) {
      value.forEach((element) => {
        searchParams.append(key, element)
      })
    } else {
      searchParams.append(key, value)
    }
  }
  return searchParams
}

export function urlSearchParamsToParsedUrlQuery(
  searchParams: URLSearchParams
): ParsedUrlQuery {
  const query: ParsedUrlQuery = {}
  for (var [key, value] of searchParams.entries()) {
    query[key] = value
  }
  return query
}

If you want, you can also create another helper method to transform the query object from next/router to an encoded string

export function parsedUrlQueryToURLString(query: ParsedUrlQuery): string {
  const params = []
  for (const [key, value] of Object.entries(query)) {
    if (!value) continue
    if (Array.isArray(value)) {
      value.forEach((element) => {
        params.push(`${key}=${encodeURIComponent(element)}`)
      })
    } else {
      params.push(`${key}=${encodeURIComponent(value)}`)
    }
  }
  return params.join('&')
}
giorgiline
  • 1,271
  • 4
  • 21
  • 35