From bb0d1bfa636fad43f5156e7622464849625adae5 Mon Sep 17 00:00:00 2001 From: rk Date: Thu, 22 Oct 2026 14:16:28 +0500 Subject: [PATCH 1/2] fix(typescript-angular): skip null and undefined fields in non-exploded object query params --- .../typescript-angular/queryParams.mustache | 10 +++++++--- .../query-param-deep-object/query.params.ts | 10 +++++++--- .../builds/query-param-form-dot/query.params.ts | 10 +++++++--- .../builds/query-param-form/query.params.ts | 10 +++++++--- .../builds/query-param-json/query.params.ts | 10 +++++++--- .../projects/app/src/api.query_param_form.spec.ts | 15 +++++++++++++++ .../query.params.ts | 10 +++++++--- .../builds/composed-schemas/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- .../builds/with-http-resource/query.params.ts | 10 +++++++--- .../builds/default/query.params.ts | 10 +++++++--- 19 files changed, 141 insertions(+), 54 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache index 4076c1140c83..5bdebb528dee 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts b/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts index d0994e2a8822..d42accdd8934 100644 --- a/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts +++ b/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts @@ -7,6 +7,7 @@ import {DefaultService, Filter, provideApi} from '@swagger/typescript-angular-qu const ids: number[] = [4, 5]; const filter: Filter = {name: 'John', age: 37, nicknames: ['Joe', 'Joey']}; const filterWithSpecialCharacters: Filter = {name: 'Éléonore &,|+', age: 42, nicknames: ['Elé', 'Ellie']}; +const filterWithUndefined: Filter = {name: 'John', age: undefined, nicknames: ['Joe']}; const country: string = "Belgium"; const tags: Set = new Set(['a', 'b']); @@ -75,6 +76,13 @@ describe('Form Query Param testing', () => { expect(req.request.method).toEqual('GET'); }); + it('should separate the query parameter with ampersands (object with undefined field)', async () => { + service.searchExplode(undefined, filterWithUndefined, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_explode?name=John&nicknames=Joe'); + expect(req.request.method).toEqual('GET'); + }); + it('should separate the query parameter with ampersands (simple only)', async () => { service.searchExplode(undefined, undefined, country).subscribe(); const req = httpTesting.expectOne('http://localhost/search_explode?country=Belgium'); @@ -133,6 +141,13 @@ describe('Form Query Param testing', () => { expect(req.request.method).toEqual('GET'); }); + it('should separate the query parameter with comma (object with undefined field)', async () => { + service.searchNotExplode(undefined, filterWithUndefined, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_not_explode?filter=name,John,nicknames,Joe'); + expect(req.request.method).toEqual('GET'); + }); + it('should separate the query parameter with comma (simple only)', async () => { service.searchNotExplode(undefined, undefined, country).subscribe(); const req = httpTesting.expectOne('http://localhost/search_not_explode?country=Belgium'); diff --git a/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts b/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts +++ b/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts b/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts +++ b/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } diff --git a/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts index 4076c1140c83..5bdebb528dee 100644 --- a/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts @@ -137,12 +137,16 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin let keyAndValues: string[] = []; for (const k in item) { - keyAndValues.push(k); - const value = item[k]; + if (value === null || value === undefined) { + continue; + } + + keyAndValues.push(k); + if (Array.isArray(value)) { - keyAndValues.push(...value.map(convertToString)); + keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); } else { keyAndValues.push(convertToString(value)); } From c78a6987f73c39a8f2419f589ca5257c6bd26c80 Mon Sep 17 00:00:00 2001 From: rk Date: Thu, 22 Oct 2026 14:36:13 +0500 Subject: [PATCH 2/2] fix(typescript-angular): skip array fields without items in non-exploded object query params --- .../typescript-angular/queryParams.mustache | 10 +++--- .../query-param-deep-object/query.params.ts | 10 +++--- .../query-param-form-dot/query.params.ts | 10 +++--- .../builds/query-param-form/query.params.ts | 10 +++--- .../builds/query-param-json/query.params.ts | 10 +++--- .../app/src/api.query_param_form.spec.ts | 32 +++++++++++++++++++ .../query.params.ts | 10 +++--- .../builds/composed-schemas/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- .../builds/with-http-resource/query.params.ts | 10 +++--- .../builds/default/query.params.ts | 10 +++--- 19 files changed, 140 insertions(+), 72 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache index 5bdebb528dee..978fde0d2ea2 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/queryParams.mustache @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-deep-object/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-form-dot/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-form/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts b/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts +++ b/samples/client/others/typescript-angular-v20/builds/query-param-json/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts b/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts index d42accdd8934..6397a53f753a 100644 --- a/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts +++ b/samples/client/others/typescript-angular-v20/projects/app/src/api.query_param_form.spec.ts @@ -8,6 +8,10 @@ const ids: number[] = [4, 5]; const filter: Filter = {name: 'John', age: 37, nicknames: ['Joe', 'Joey']}; const filterWithSpecialCharacters: Filter = {name: 'Éléonore &,|+', age: 42, nicknames: ['Elé', 'Ellie']}; const filterWithUndefined: Filter = {name: 'John', age: undefined, nicknames: ['Joe']}; +const filterAllUndefined: Filter = {name: undefined, age: undefined, nicknames: undefined}; +const filterWithNullItems = {name: 'John', nicknames: ['Joe', null, undefined]} as unknown as Filter; +const filterWithOnlyNullItems = {name: 'John', nicknames: [null, undefined], age: 37} as unknown as Filter; +const filterWithEmptyArray: Filter = {name: 'John', nicknames: [], age: 37}; const country: string = "Belgium"; const tags: Set = new Set(['a', 'b']); @@ -148,6 +152,34 @@ describe('Form Query Param testing', () => { expect(req.request.method).toEqual('GET'); }); + it('should separate the query parameter with comma (object with all fields undefined)', async () => { + service.searchNotExplode(undefined, filterAllUndefined, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_not_explode?filter='); + expect(req.request.method).toEqual('GET'); + }); + + it('should separate the query parameter with comma (object with null array items)', async () => { + service.searchNotExplode(undefined, filterWithNullItems, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_not_explode?filter=name,John,nicknames,Joe'); + expect(req.request.method).toEqual('GET'); + }); + + it('should separate the query parameter with comma (object with only null array items)', async () => { + service.searchNotExplode(undefined, filterWithOnlyNullItems, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_not_explode?filter=name,John,age,37'); + expect(req.request.method).toEqual('GET'); + }); + + it('should separate the query parameter with comma (object with empty array field)', async () => { + service.searchNotExplode(undefined, filterWithEmptyArray, undefined).subscribe(); + + const req = httpTesting.expectOne('http://localhost/search_not_explode?filter=name,John,age,37'); + expect(req.request.method).toEqual('GET'); + }); + it('should separate the query parameter with comma (simple only)', async () => { service.searchNotExplode(undefined, undefined, country).subscribe(); const req = httpTesting.expectOne('http://localhost/search_not_explode?country=Belgium'); diff --git a/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts b/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts +++ b/samples/client/others/typescript-angular/builds/composed-schemas-tagged-unions/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts b/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts +++ b/samples/client/others/typescript-angular/builds/composed-schemas/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v18-provided-in-root/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v19/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v20/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v21-provided-in-root/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v21/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22-provided-in-root/builds/with-http-resource/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } } diff --git a/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts b/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts index 5bdebb528dee..978fde0d2ea2 100644 --- a/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts +++ b/samples/client/petstore/typescript-angular-v22/builds/default/query.params.ts @@ -143,12 +143,14 @@ export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: strin continue; } - keyAndValues.push(k); - if (Array.isArray(value)) { - keyAndValues.push(...value.filter(v => v !== null && v !== undefined).map(convertToString)); + const items = value.filter(v => v !== null && v !== undefined); + + if (items.length > 0) { + keyAndValues.push(k, ...items.map(convertToString)); + } } else { - keyAndValues.push(convertToString(value)); + keyAndValues.push(k, convertToString(value)); } }