diff --git a/packages/x-adapter/src/http-clients/__tests__/fetch.http-client.spec.ts b/packages/x-adapter/src/http-clients/__tests__/fetch.http-client.spec.ts index 67b7860dbb..bf21b575b0 100644 --- a/packages/x-adapter/src/http-clients/__tests__/fetch.http-client.spec.ts +++ b/packages/x-adapter/src/http-clients/__tests__/fetch.http-client.spec.ts @@ -59,6 +59,20 @@ describe('fetch httpClient testing', () => { expectFetchCallWith(endpoint); }); + it('maps empty values if configured to do so', async () => { + await fetchHttpClient(endpoint, { + sendEmptyParams: true, + parameters: { + q: undefined, + r: '', + s: null, + t: [], + u: {} + } + }); + expectFetchCallWith(`${endpoint}?r=&s=null`); + }); + it('cancels equal endpoint requests if no requestId parameter is passed', async () => { await Promise.all([ expect( @@ -186,6 +200,43 @@ describe('fetch httpClient testing', () => { }) }); }); + + it('sends empty values in the body if configured to do so', async () => { + await fetchHttpClient(endpoint, { + sendParamsInBody: true, + sendEmptyParams: true, + parameters: { + q: 'shirt', + a: undefined, + b: null, + c: '', + d: [], + extraParams: { + lang: 'en', + e: undefined, + f: null, + g: '', + h: [], + i: {} + } + } + }); + expectFetchCallWith(endpoint, { + body: JSON.stringify({ + q: 'shirt', + b: null, + c: '', + d: [], + extraParams: { + lang: 'en', + f: null, + g: '', + h: [], + i: {} + } + }) + }); + }); }); }); diff --git a/packages/x-adapter/src/http-clients/fetch.http-client.ts b/packages/x-adapter/src/http-clients/fetch.http-client.ts index bee015d17a..75ea20dac5 100644 --- a/packages/x-adapter/src/http-clients/fetch.http-client.ts +++ b/packages/x-adapter/src/http-clients/fetch.http-client.ts @@ -14,12 +14,22 @@ import { buildUrl, toJson } from './utils'; */ export const fetchHttpClient: HttpClient = ( endpoint, - { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {} + { + id = endpoint, + cancelable = true, + parameters = {}, + properties, + sendParamsInBody = false, + sendEmptyParams = false + } = {} ) => { const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {}; + if (!sendEmptyParams) { + parameters = cleanEmpty(parameters); + } const flatParameters = flatObject(parameters); - const url = sendParamsInBody ? endpoint : buildUrl(endpoint, cleanEmpty(flatParameters)); - const bodyParameters = sendParamsInBody ? { body: JSON.stringify(cleanEmpty(parameters)) } : {}; + const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters); + const bodyParameters = sendParamsInBody ? { body: JSON.stringify(parameters) } : {}; return fetch(url, { ...properties, diff --git a/packages/x-adapter/src/http-clients/types.ts b/packages/x-adapter/src/http-clients/types.ts index b578ca8117..b218531dda 100644 --- a/packages/x-adapter/src/http-clients/types.ts +++ b/packages/x-adapter/src/http-clients/types.ts @@ -31,6 +31,10 @@ export interface RequestOptions { * A flag to send parameters in the body if true or in the url QueryString if false. */ sendParamsInBody?: boolean; + /** + * A flag to always send the parameters even if their values are empty. + */ + sendEmptyParams?: boolean; /** * A list of parameters to send to the API. */