Skip to content

Commit 13d48e2

Browse files
authored
Merge pull request #2904 from tophep/feature/add-json-replacer-to-fetchBaseQuery
2 parents 37a33fb + 8c380c2 commit 13d48e2

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

packages/toolkit/src/query/fetchBaseQuery.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ export type FetchBaseQueryArgs = {
132132
* Defaults to `application/json`;
133133
*/
134134
jsonContentType?: string
135+
136+
/**
137+
* Custom replacer function used when calling `JSON.stringify()`;
138+
*/
139+
jsonReplacer?: (this: any, key: string, value: any) => any
135140
} & RequestInit &
136141
Pick<FetchArgs, 'responseHandler' | 'validateStatus' | 'timeout'>
137142

@@ -178,6 +183,8 @@ export type FetchBaseQueryMeta = { request: Request; response?: Response }
178183
*
179184
* @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`.
180185
*
186+
* @param {(this: any, key: string, value: any) => any} jsonReplacer Custom replacer function used when calling `JSON.stringify()`.
187+
*
181188
* @param {number} timeout
182189
* A number in milliseconds that represents the maximum time a request can take before timing out.
183190
*/
@@ -188,6 +195,7 @@ export function fetchBaseQuery({
188195
paramsSerializer,
189196
isJsonContentType = defaultIsJsonContentType,
190197
jsonContentType = 'application/json',
198+
jsonReplacer,
191199
timeout: defaultTimeout,
192200
validateStatus: globalValidateStatus,
193201
...baseFetchOptions
@@ -247,7 +255,7 @@ export function fetchBaseQuery({
247255
}
248256

249257
if (isJsonifiable(body) && isJsonContentType(config.headers)) {
250-
config.body = JSON.stringify(body)
258+
config.body = JSON.stringify(body, jsonReplacer)
251259
}
252260

253261
if (params) {

packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,47 @@ describe('fetchBaseQuery', () => {
431431

432432
expect(request.headers['content-type']).toBe('application/vnd.api+json')
433433
})
434+
435+
it('supports a custom jsonReplacer', async () => {
436+
const body = {
437+
items: new Set(["A", "B", "C"])
438+
}
439+
440+
let request: any
441+
;({ data: request } = await baseQuery(
442+
{
443+
url: '/echo',
444+
body,
445+
method: 'POST',
446+
},
447+
commonBaseQueryApi,
448+
{}
449+
))
450+
451+
expect(request.headers['content-type']).toBe('application/json')
452+
expect(request.body).toEqual({ items: {} }) // Set is not properly marshalled by default
453+
454+
// Use jsonReplacer
455+
const baseQueryWithReplacer = fetchBaseQuery({
456+
baseUrl,
457+
fetchFn: fetchFn as any,
458+
jsonReplacer: (key, value) => value instanceof Set ? [...value] : value
459+
})
460+
461+
;({ data: request } = await baseQueryWithReplacer(
462+
{
463+
url: '/echo',
464+
body,
465+
method: 'POST',
466+
},
467+
commonBaseQueryApi,
468+
{}
469+
))
470+
471+
expect(request.headers['content-type']).toBe('application/json')
472+
expect(request.body).toEqual({ items: ["A", "B", "C"] }) // Set is marshalled correctly by jsonReplacer
473+
474+
})
434475
})
435476

436477
describe('arg.params', () => {

0 commit comments

Comments
 (0)