I'm having a bit of a problem with a custom serializer in flutter ferry graphql package:
I have used exactly the example from the ferry docs: https://ferrygraphql.com/docs/custom-scalars/#create-a-custom-serializer
But I always get the following message when running the builder_runner:
[SEVERE] built_value_generator:built_value on lib/schema.schema.gql.dart:
Error in BuiltValueGenerator for abstract class GDailyForecastInput implements Built<GDailyForecastInput, dynamic>.
Please make the following changes to use BuiltValue:
1. Make field dateStart have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
2. Make field dateEnd have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
[SEVERE] built_value_generator:built_value on lib/schema.schema.gql.dart:
Error in BuiltValueGenerator for abstract class GHourlyForecastInput implements Built<GHourlyForecastInput, dynamic>.
Please make the following changes to use BuiltValue:
1. Make field dateStart have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
2. Make field dateEnd have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
dateStart and dateEnd are query input values of type Date This is my type overwrite: type_overrides: Date: name: Date Does anyone one why this error happens? I really can't find out what the problem is
Date is define das a scalar in my schema.graphql file:
"""A date string with format `Y-m-d`, e.g. `2011-05-23`."""
scalar Date
Here is my build.yaml file:
targets:
$default:
builders:
gql_build|schema_builder:
enabled: true
options:
type_overrides:
Date:
name: Date
gql_build|ast_builder:
enabled: true
options:
type_overrides:
Date:
name: Date
gql_build|data_builder:
enabled: true
options:
type_overrides:
Date:
name: Date
schema: appdemo|lib/schema.graphql
gql_build|var_builder:
enabled: true
options:
type_overrides:
Date:
name: Date
schema: appdemo|lib/schema.graphql
gql_build|serializer_builder:
enabled: true
options:
schema: appdemo|lib/schema.graphql
custom_serializers:
- import: './serializers/date_serializer.dart'
name: DateSerializer
ferry_generator|req_builder:
enabled: true
options:
type_overrides:
Date:
name: Date
schema: appdemo|lib/schema.graphql
I tried debugging already. If I rename my scalar to DateTime
everything works fine.
(I also have a scalar DateTime
in my schema.graphql
file.)
It's only if I use the name Date
that I get this error.
Am I missing something?
Do I need to create additionally to the code in the documention a dart Date
class and link it or so?
Make sure you also include type_overrides for data_builder, var_builder, and req_builder.
IMPORTANT We've included only the schema_builder above for brevity, but we will need to include this same type_overrides map for data_builder, var_builder, and req_builder as well. See the complete build.yaml example for more details.
For example:
Let's say I have two custom scalar, a primitive and a non-primitive type,
schema.graphql
:
scalar Date #A datetime string in iso8601.
scalar Metadata #A map with key string and value any.
type Test {
id: ID!
date: Date!
metadata: Metadata!
}
type Query {
getTest(): Test!
}
date_serializer.dart
:
import 'package:built_value/serializer.dart';
class DateSerializer implements PrimitiveSerializer<DateTime> {
@override
DateTime deserialize(
Serializers serializers,
Object serialized, {
FullType specifiedType = FullType.unspecified,
}) {
assert(serialized is String,
"DateSerializer expected 'String' but got ${serialized.runtimeType}");
return DateTime.parse(serialized is String ? serialized : "");
}
@override
Object serialize(
Serializers serializers,
DateTime date, {
FullType specifiedType = FullType.unspecified,
}) =>
date.toUtc().toIso8601String();
@override
Iterable<Type> get types => [DateTime];
@override
String get wireName => "Date";
}
metadata_serializer.dart
:
import "package:gql_code_builder/src/serializers/json_serializer.dart";
class MetadataSerializer extends JsonSerializer<Map<String, dynamic>> {
@override
Map<String, dynamic> fromJson(Map<String, dynamic> json) => json;
@override
Map<String, dynamic> toJson(Map<String, dynamic> map) => map;
}
build.yaml
:
targets:
$default:
builders:
gql_build|schema_builder:
enabled: true
options:
type_overrides:
Metadata:
name: Map<String, dynamic>
Date:
name: DateTime
gql_build|ast_builder:
enabled: true
gql_build|data_builder:
enabled: true
options:
schema: my_project|lib/schema.graphql
type_overrides:
Metadata:
name: Map<String, dynamic>
Date:
name: DateTime
gql_build|var_builder:
enabled: true
options:
schema: my_project|lib/schema.graphql
type_overrides:
Metadata:
name: Map<String, dynamic>
Date:
name: DateTime
gql_build|serializer_builder:
enabled: true
options:
schema: my_project|lib/schema.graphql
custom_serializers:
- import: 'path/to/metadata_serializer.dart'
name: MetadataSerializer
- import: 'path/to/date_serializer.dart'
name: DateSerializer
ferry_generator|req_builder:
enabled: true
options:
schema: my_project|lib/schema.graphql
type_overrides:
Metadata:
name: Map<String, dynamic>
Date:
name: DateTime
After build you should now have both scalar overridden,
test.dart
:
client.request(request).first.then((response){
print(response.data?.test.date.runtimeType);
print(response.data?.test.metadata.runtimeType);
})
output
:
DateTime
JsLinkedHashMap<String, dynamic>