diff --git a/packages/http-client-js/src/components/http-request-parameters-expression.tsx b/packages/http-client-js/src/components/http-request-parameters-expression.tsx
index f38da9ec411..dc248bffb58 100644
--- a/packages/http-client-js/src/components/http-request-parameters-expression.tsx
+++ b/packages/http-client-js/src/components/http-request-parameters-expression.tsx
@@ -53,7 +53,7 @@ export function HttpRequestParametersExpression(props: HttpRequestParametersExpr
if (propertyExpression.isNullish) {
return code`
- ...(${propertyExpression.fullExpression} && {${()}})
+ ...(${propertyExpression.fullExpression} != undefined && {${()}})
`;
} else {
return (
diff --git a/packages/http-client-js/test/scenarios/encoding/header_bytes.md b/packages/http-client-js/test/scenarios/encoding/header_bytes.md
index 3bc1c915bd3..982d6ced1a2 100644
--- a/packages/http-client-js/test/scenarios/encoding/header_bytes.md
+++ b/packages/http-client-js/test/scenarios/encoding/header_bytes.md
@@ -68,7 +68,7 @@ export async function defaultEncoding(
const path = parse("/default").expand({});
const httpRequestOptions = {
headers: {
- ...(options?.value && {
+ ...(options?.value != undefined && {
value: encodeUint8Array(options.value, "base64")!,
}),
},
diff --git a/packages/http-client-js/test/scenarios/encoding/header_date.md b/packages/http-client-js/test/scenarios/encoding/header_date.md
index f7ace86237f..b6be9b50be3 100644
--- a/packages/http-client-js/test/scenarios/encoding/header_date.md
+++ b/packages/http-client-js/test/scenarios/encoding/header_date.md
@@ -68,7 +68,9 @@ export async function defaultEncoding(
const path = parse("/default").expand({});
const httpRequestOptions = {
headers: {
- ...(options?.value && { value: dateRfc7231Serializer(options.value) }),
+ ...(options?.value != undefined && {
+ value: dateRfc7231Serializer(options.value),
+ }),
},
};
const response = await client.pathUnchecked(path).get(httpRequestOptions);
diff --git a/packages/http-client-js/test/scenarios/encoding/query_date.md b/packages/http-client-js/test/scenarios/encoding/query_date.md
index bf3087b6951..284476a182f 100644
--- a/packages/http-client-js/test/scenarios/encoding/query_date.md
+++ b/packages/http-client-js/test/scenarios/encoding/query_date.md
@@ -66,7 +66,9 @@ export async function defaultEncoding(
options?: DefaultEncodingOptions,
): Promise {
const path = parse("/default{?value}").expand({
- ...(options?.value && { value: dateRfc3339Serializer(options.value) }),
+ ...(options?.value != undefined && {
+ value: dateRfc3339Serializer(options.value),
+ }),
});
const httpRequestOptions = {
headers: {},
diff --git a/packages/http-client-js/test/scenarios/http-operations/basic-request.md b/packages/http-client-js/test/scenarios/http-operations/basic-request.md
index 939accf720b..0aabf26489b 100644
--- a/packages/http-client-js/test/scenarios/http-operations/basic-request.md
+++ b/packages/http-client-js/test/scenarios/http-operations/basic-request.md
@@ -142,3 +142,55 @@ export async function read(
throw createRestError(response);
}
```
+
+# Should preserve falsy optional HTTP parameters
+
+This test verifies optional query and header parameters are emitted when their value is falsy but present.
+
+## TypeSpec
+
+```tsp
+@service(#{ title: "Widget Service" })
+namespace DemoService;
+
+@route("/widgets")
+@tag("Widgets")
+interface Widgets {
+ @test
+ @get
+ read(
+ @query isActive?: boolean,
+ @query count?: int32,
+ @query filter?: string,
+ @header ifMatch?: string,
+ ): void;
+}
+```
+
+## TypeScript
+
+### Request
+
+```ts src/api/widgetsClient/widgetsClientOperations.ts function read
+export async function read(client: WidgetsClientContext, options?: ReadOptions): Promise {
+ const path = parse("/widgets{?isActive,count,filter}").expand({
+ ...(options?.isActive != undefined && { isActive: options.isActive }),
+ ...(options?.count != undefined && { count: options.count }),
+ ...(options?.filter != undefined && { filter: options.filter }),
+ });
+ const httpRequestOptions = {
+ headers: {
+ ...(options?.ifMatch != undefined && { "if-match": options.ifMatch }),
+ },
+ };
+ const response = await client.pathUnchecked(path).get(httpRequestOptions);
+
+ if (typeof options?.operationOptions?.onResponse === "function") {
+ options?.operationOptions?.onResponse(response);
+ }
+ if (+response.status === 204 && !response.body) {
+ return;
+ }
+ throw createRestError(response);
+}
+```
diff --git a/packages/http-client-js/test/scenarios/http-operations/paging.md b/packages/http-client-js/test/scenarios/http-operations/paging.md
index 4d763b04685..374b659a0a9 100644
--- a/packages/http-client-js/test/scenarios/http-operations/paging.md
+++ b/packages/http-client-js/test/scenarios/http-operations/paging.md
@@ -53,7 +53,7 @@ export function link(
async function linkSend(client: TestClientContext, filter: string, options?: Record) {
const path = parse("/link{?filter,nextToken}").expand({
filter: filter,
- ...(options?.nextToken && { nextToken: options.nextToken }),
+ ...(options?.nextToken != undefined && { nextToken: options.nextToken }),
});
const httpRequestOptions = {
headers: {},
@@ -174,7 +174,9 @@ export function link(
async function linkSend(client: TestClientContext, filter: string, options?: Record) {
const path = parse("/link{?filter,maxPageSize}").expand({
filter: filter,
- ...(options?.maxPageSize && { maxPageSize: options.maxPageSize }),
+ ...(options?.maxPageSize != undefined && {
+ maxPageSize: options.maxPageSize,
+ }),
});
const httpRequestOptions = {
headers: {},
diff --git a/packages/http-client-js/test/scenarios/http-operations/query-parameter.md b/packages/http-client-js/test/scenarios/http-operations/query-parameter.md
index c29d575ff08..9cd81aadb04 100644
--- a/packages/http-client-js/test/scenarios/http-operations/query-parameter.md
+++ b/packages/http-client-js/test/scenarios/http-operations/query-parameter.md
@@ -24,7 +24,7 @@ export async function headModel(
const path = parse("/").expand({});
const httpRequestOptions = {
headers: {
- ...(input.foo && { foo: input.foo }),
+ ...(input.foo != undefined && { foo: input.foo }),
},
body: jsonVisibilityModelToTransportTransform(input),
};
diff --git a/packages/http-client-js/test/scenarios/operation-parameters/body_root_anonymous.md b/packages/http-client-js/test/scenarios/operation-parameters/body_root_anonymous.md
index a33507c5ff6..20a306a324d 100644
--- a/packages/http-client-js/test/scenarios/operation-parameters/body_root_anonymous.md
+++ b/packages/http-client-js/test/scenarios/operation-parameters/body_root_anonymous.md
@@ -32,7 +32,7 @@ export async function create(
const path = parse("/").expand({});
const httpRequestOptions = {
headers: {
- ...(widget.foo && { foo: widget.foo }),
+ ...(widget.foo != undefined && { foo: widget.foo }),
},
body: {
id: widget.id,
diff --git a/packages/http-client-js/test/scenarios/operation-parameters/with_body_property.md b/packages/http-client-js/test/scenarios/operation-parameters/with_body_property.md
index ff0787efd73..1434a52e982 100644
--- a/packages/http-client-js/test/scenarios/operation-parameters/with_body_property.md
+++ b/packages/http-client-js/test/scenarios/operation-parameters/with_body_property.md
@@ -26,7 +26,7 @@ export async function create(
const path = parse("/").expand({});
const httpRequestOptions = {
headers: {
- ...(options?.foo && { foo: options.foo }),
+ ...(options?.foo != undefined && { foo: options.foo }),
},
body: jsonWidgetToTransportTransform(widget),
};
diff --git a/packages/http-client-js/test/scenarios/operation-parameters/with_body_root.md b/packages/http-client-js/test/scenarios/operation-parameters/with_body_root.md
index a9f651a40cf..a2a6604ec89 100644
--- a/packages/http-client-js/test/scenarios/operation-parameters/with_body_root.md
+++ b/packages/http-client-js/test/scenarios/operation-parameters/with_body_root.md
@@ -27,7 +27,7 @@ export async function create(
const path = parse("/").expand({});
const httpRequestOptions = {
headers: {
- ...(widget.foo && { foo: widget.foo }),
+ ...(widget.foo != undefined && { foo: widget.foo }),
},
body: jsonWidgetToTransportTransform(widget),
};