From 5a34b58dbbd07647c2b7eae8e878cfbb7219ed9e Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 10 Nov 2025 17:30:06 +0530 Subject: [PATCH 1/4] fix: strip non-nullable optional params in Dart/Flutter SDKs This change updates the Dart and Flutter SDK templates to conditionally include non-nullable optional parameters in the request params map only when they are not null. Previously, all parameters were always included in the params map, which could lead to unnecessary null values being sent in API requests. This implementation matches the Python SDK behavior (templates/python/base/params.twig) where optional non-nullable parameters are checked with "if not None" before being added to api_params. Changes: - Modified templates/dart/base/utils.twig map_parameter macro - Modified templates/flutter/base/utils.twig map_parameter macro - Uses Dart's collection-if syntax for conditional parameter inclusion - Adds null assertion operator (!) for enum values when inside null check Example generated code: ```dart final Map apiParams = { 'requiredParam': requiredParam, if (optionalParam != null) 'optionalParam': optionalParam, }; ``` --- templates/dart/base/utils.twig | 4 ++++ templates/flutter/base/utils.twig | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/templates/dart/base/utils.twig b/templates/dart/base/utils.twig index df33f1a330..df4885b8c8 100644 --- a/templates/dart/base/utils.twig +++ b/templates/dart/base/utils.twig @@ -1,6 +1,10 @@ {% macro map_parameter(parameters) %} {% for parameter in parameters %} +{% if not parameter.nullable and not parameter.required %} +if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!{% endif %}{% if parameter.enumValues | length > 0 %}.value{% endif %}, +{% else %} '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}{% if not parameter.required %}?{% endif %}.value{% endif %}, +{% endif %} {% endfor %} {% endmacro %} diff --git a/templates/flutter/base/utils.twig b/templates/flutter/base/utils.twig index 3927955752..b3a2ca30c1 100644 --- a/templates/flutter/base/utils.twig +++ b/templates/flutter/base/utils.twig @@ -1,6 +1,10 @@ {%- macro map_parameter(parameters) -%} {%- for parameter in parameters ~%} +{% if not parameter.nullable and not parameter.required %} + if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!{% endif %}{% if parameter.enumValues | length > 0 %}.value{% endif %}, +{% else %} '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}{% if not parameter.required %}?{% endif %}.value{% endif %}, +{% endif %} {%- endfor ~%} {%- endmacro ~%} From e4f2bef41c3087a00b9996a92e7128041d4f55cc Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 10 Nov 2025 17:32:33 +0530 Subject: [PATCH 2/4] include removal of stripping null values --- templates/dart/lib/src/client_mixin.dart.twig | 3 --- templates/flutter/lib/src/client_mixin.dart.twig | 3 --- 2 files changed, 6 deletions(-) diff --git a/templates/dart/lib/src/client_mixin.dart.twig b/templates/dart/lib/src/client_mixin.dart.twig index a2340377fd..1483c29456 100644 --- a/templates/dart/lib/src/client_mixin.dart.twig +++ b/templates/dart/lib/src/client_mixin.dart.twig @@ -12,9 +12,6 @@ mixin ClientMixin { required Map headers, required Map params, }) { - if (params.isNotEmpty) { - params.removeWhere((key, value) => value == null); - } http.BaseRequest request = http.Request(method.name(), uri); if (headers['content-type'] == 'multipart/form-data') { diff --git a/templates/flutter/lib/src/client_mixin.dart.twig b/templates/flutter/lib/src/client_mixin.dart.twig index 5cdd9d3109..c38a48f253 100644 --- a/templates/flutter/lib/src/client_mixin.dart.twig +++ b/templates/flutter/lib/src/client_mixin.dart.twig @@ -12,9 +12,6 @@ mixin ClientMixin { required Map headers, required Map params, }) { - if (params.isNotEmpty) { - params.removeWhere((key, value) => value == null); - } http.BaseRequest request = http.Request(method.name(), uri); if (headers['content-type'] == 'multipart/form-data') { From ecfc5fb0d0e2847a53a935f24f7cf8edfbcc125d Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 12 Nov 2025 14:21:00 +0530 Subject: [PATCH 3/4] fix: duplicacy --- templates/dart/base/utils.twig | 2 +- templates/flutter/base/utils.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/dart/base/utils.twig b/templates/dart/base/utils.twig index df4885b8c8..876f92859d 100644 --- a/templates/dart/base/utils.twig +++ b/templates/dart/base/utils.twig @@ -1,7 +1,7 @@ {% macro map_parameter(parameters) %} {% for parameter in parameters %} {% if not parameter.nullable and not parameter.required %} -if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!{% endif %}{% if parameter.enumValues | length > 0 %}.value{% endif %}, +if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!.value{% endif %}, {% else %} '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}{% if not parameter.required %}?{% endif %}.value{% endif %}, {% endif %} diff --git a/templates/flutter/base/utils.twig b/templates/flutter/base/utils.twig index b3a2ca30c1..0ffa596590 100644 --- a/templates/flutter/base/utils.twig +++ b/templates/flutter/base/utils.twig @@ -1,7 +1,7 @@ {%- macro map_parameter(parameters) -%} {%- for parameter in parameters ~%} {% if not parameter.nullable and not parameter.required %} - if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!{% endif %}{% if parameter.enumValues | length > 0 %}.value{% endif %}, + if ({{ parameter.name | caseCamel | overrideIdentifier }} != null) '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}!.value{% endif %}, {% else %} '{{ parameter.name }}': {{ parameter.name | caseCamel | overrideIdentifier }}{% if parameter.enumValues | length > 0 %}{% if not parameter.required %}?{% endif %}.value{% endif %}, {% endif %} From 3c12f4685734135ef637d68e1b861f9f975fa85c Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 12 Nov 2025 14:25:03 +0530 Subject: [PATCH 4/4] filter null values in multi part and get requests --- templates/dart/lib/src/client_mixin.dart.twig | 29 ++++++++++++------- .../flutter/lib/src/client_mixin.dart.twig | 29 ++++++++++++------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/templates/dart/lib/src/client_mixin.dart.twig b/templates/dart/lib/src/client_mixin.dart.twig index 1483c29456..d2b5569982 100644 --- a/templates/dart/lib/src/client_mixin.dart.twig +++ b/templates/dart/lib/src/client_mixin.dart.twig @@ -18,14 +18,19 @@ mixin ClientMixin { request = http.MultipartRequest(method.name(), uri); if (params.isNotEmpty) { params.forEach((key, value) { + if (value == null) { + return; + } if (value is http.MultipartFile) { (request as http.MultipartRequest).files.add(value); } else { if (value is List) { value.asMap().forEach((i, v) { - (request as http.MultipartRequest) - .fields - .addAll({"$key[$i]": v.toString()}); + if (v != null) { + (request as http.MultipartRequest) + .fields + .addAll({"$key[$i]": v.toString()}); + } }); } else { (request as http.MultipartRequest) @@ -37,15 +42,19 @@ mixin ClientMixin { } } else if (method == HttpMethod.get) { if (params.isNotEmpty) { - params = params.map((key, value){ - if (value is int || value is double) { - return MapEntry(key, value.toString()); - } - if (value is List) { - return MapEntry("$key[]", value); + Map filteredParams = {}; + params.forEach((key, value) { + if (value != null) { + if (value is int || value is double) { + filteredParams[key] = value.toString(); + } else if (value is List) { + filteredParams["$key[]"] = value; + } else { + filteredParams[key] = value; + } } - return MapEntry(key, value); }); + params = filteredParams; } uri = Uri( fragment: uri.fragment, diff --git a/templates/flutter/lib/src/client_mixin.dart.twig b/templates/flutter/lib/src/client_mixin.dart.twig index c38a48f253..e91cc260a3 100644 --- a/templates/flutter/lib/src/client_mixin.dart.twig +++ b/templates/flutter/lib/src/client_mixin.dart.twig @@ -18,14 +18,19 @@ mixin ClientMixin { request = http.MultipartRequest(method.name(), uri); if (params.isNotEmpty) { params.forEach((key, value) { + if (value == null) { + return; + } if (value is http.MultipartFile) { (request as http.MultipartRequest).files.add(value); } else { if (value is List) { value.asMap().forEach((i, v) { - (request as http.MultipartRequest).fields.addAll({ - "$key[$i]": v.toString(), - }); + if (v != null) { + (request as http.MultipartRequest).fields.addAll({ + "$key[$i]": v.toString(), + }); + } }); } else { (request as http.MultipartRequest).fields.addAll({ @@ -37,15 +42,19 @@ mixin ClientMixin { } } else if (method == HttpMethod.get) { if (params.isNotEmpty) { - params = params.map((key, value){ - if (value is int || value is double) { - return MapEntry(key, value.toString()); - } - if (value is List) { - return MapEntry("$key[]", value); + Map filteredParams = {}; + params.forEach((key, value) { + if (value != null) { + if (value is int || value is double) { + filteredParams[key] = value.toString(); + } else if (value is List) { + filteredParams["$key[]"] = value; + } else { + filteredParams[key] = value; + } } - return MapEntry(key, value); }); + params = filteredParams; } uri = Uri( fragment: uri.fragment,