-
Notifications
You must be signed in to change notification settings - Fork 133
Description
Description
When using Ferry with JsonObject type (from built_value package) and tristate_optionals: true option enabled, the generated serializer code contains calls to .replace() method on JsonObject? fields, but JsonObject doesn't have a replace method.
Important: This error only occurs when tristate_optionals: true is set in the build configuration.
Environment
- Ferry version: Latest
- built_value version: 8.11.1
- Flutter/Dart SDK: Latest stable
Reproduction Steps
- Define a GraphQL schema with JSON scalar type:
scalar JSON- Configure
build.yamlwith type override and tristate_optionals enabled:
targets:
$default:
builders:
ferry_generator|graphql_builder:
options:
schema: path/to/schema.graphql
tristate_optionals: true # ← This triggers the issue
type_overrides:
JSON:
name: JsonObject
import: "package:built_value/json_object.dart"- Generate code using
build_runner
Generated Code Issue
The generated serializer code produces:
// In schema.schema.gql.dart
case 'params':
var _$fieldValue = serializers.deserialize(value,
specifiedType: const FullType(_i1.JsonObject)) as _i1.JsonObject;
builder.params.replace(_$fieldValue); // ❌ Error here
break;
case 'body':
var _$fieldValue = serializers.deserialize(value,
specifiedType: const FullType(_i1.JsonObject)) as _i1.JsonObject;
builder.body.replace(_$fieldValue); // ❌ Error here
break;Error Message
Error: The method 'replace' isn't defined for type 'JsonObject?'.
- 'JsonObject' is from 'package:built_value/json_object.dart'
Try correcting the name to the name of an existing method, or defining a method named 'replace'.
builder.params.replace(_$fieldValue);
^^^^^^^
Expected Behavior
The generated code should use proper assignment for JsonObject fields instead of calling .replace() method, similar to how other non-built types are handled:
// Should be:
builder.params = _$fieldValue;
// Instead of:
builder.params.replace(_$fieldValue);Additional Context
- The issue does not occur when
tristate_optionals: false(or omitted) - Looking at the generated
.g.dartfile, the builder has simple setters forJsonObjectfields:
_i1.JsonObject? _params;
_i1.JsonObject? get params => _$this._params;
set params(_i1.JsonObject? params) => _$this._params = params;The issue seems to be that when tristate_optionals is enabled, the code generator incorrectly treats JsonObject as a built collection type that has a replace method, when it should treat it as a simple value type.
Workaround
Disabling tristate_optionals avoids the issue, but this is not ideal when you need to distinguish between null and absent values in GraphQL inputs.