Skip to content

Commit

Permalink
Merge pull request #2904 from tophep/feature/add-json-replacer-to-fet…
Browse files Browse the repository at this point in the history
…chBaseQuery
  • Loading branch information
markerikson committed Jan 28, 2023
2 parents 37a33fb + 8c380c2 commit 13d48e2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/toolkit/src/query/fetchBaseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ export type FetchBaseQueryArgs = {
* Defaults to `application/json`;
*/
jsonContentType?: string

/**
* Custom replacer function used when calling `JSON.stringify()`;
*/
jsonReplacer?: (this: any, key: string, value: any) => any
} & RequestInit &
Pick<FetchArgs, 'responseHandler' | 'validateStatus' | 'timeout'>

Expand Down Expand Up @@ -178,6 +183,8 @@ export type FetchBaseQueryMeta = { request: Request; response?: Response }
*
* @param {string} jsonContentType Used when automatically setting the content-type header for a request with a jsonifiable body that does not have an explicit content-type header. Defaults to `application/json`.
*
* @param {(this: any, key: string, value: any) => any} jsonReplacer Custom replacer function used when calling `JSON.stringify()`.
*
* @param {number} timeout
* A number in milliseconds that represents the maximum time a request can take before timing out.
*/
Expand All @@ -188,6 +195,7 @@ export function fetchBaseQuery({
paramsSerializer,
isJsonContentType = defaultIsJsonContentType,
jsonContentType = 'application/json',
jsonReplacer,
timeout: defaultTimeout,
validateStatus: globalValidateStatus,
...baseFetchOptions
Expand Down Expand Up @@ -247,7 +255,7 @@ export function fetchBaseQuery({
}

if (isJsonifiable(body) && isJsonContentType(config.headers)) {
config.body = JSON.stringify(body)
config.body = JSON.stringify(body, jsonReplacer)
}

if (params) {
Expand Down
41 changes: 41 additions & 0 deletions packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,47 @@ describe('fetchBaseQuery', () => {

expect(request.headers['content-type']).toBe('application/vnd.api+json')
})

it('supports a custom jsonReplacer', async () => {
const body = {
items: new Set(["A", "B", "C"])
}

let request: any
;({ data: request } = await baseQuery(
{
url: '/echo',
body,
method: 'POST',
},
commonBaseQueryApi,
{}
))

expect(request.headers['content-type']).toBe('application/json')
expect(request.body).toEqual({ items: {} }) // Set is not properly marshalled by default

// Use jsonReplacer
const baseQueryWithReplacer = fetchBaseQuery({
baseUrl,
fetchFn: fetchFn as any,
jsonReplacer: (key, value) => value instanceof Set ? [...value] : value
})

;({ data: request } = await baseQueryWithReplacer(
{
url: '/echo',
body,
method: 'POST',
},
commonBaseQueryApi,
{}
))

expect(request.headers['content-type']).toBe('application/json')
expect(request.body).toEqual({ items: ["A", "B", "C"] }) // Set is marshalled correctly by jsonReplacer

})
})

describe('arg.params', () => {
Expand Down

0 comments on commit 13d48e2

Please sign in to comment.