In order to read from and write data with relations to the PocketBase API I need custom fromJson
and toJson
methods to de/serialize it to my models:
@freezed
class MyModel with _$MyModel {
const factory MyModel({
String name,
@RelationsConverter() List<Relation>? relations,
}) = _MyModel;
factory MyModel.fromJson(Map<String, Object?> json) => _$MyModelFromJson(json);
}
@freezed
class Relation with _$Relation {
const factory Relation({
required String id,
String name,
}) = _Relation;
factory Relation.fromJson(Map<String, Object?> json) => _$RelationFromJson(json);
}
The Json data when reading a model from PocketBase with the fields "name" and "relations", which contains a list of relations to some other model might look like this (with the expand=relations
query parameter set):
{
"name": "A model",
"relations": [
"abc123",
"def456"
],
"expand": {
"relations": [
{
"id": "abc123",
"name": "Relation A"
},
{
"id": "def456",
"name": "Relation B"
}
]
}
}
Before converting the data to my models, I transform the data so it looks like this and can be easily deserialized:
{
"name": "A model",
"relations": [
{
"id": "abc123",
"name": "Relation A"
},
{
"id": "def456",
"name": "Relation B"
}
]
}
When updating/creating data however, this form is not desired, I need it in this form:
{
"name": "An updated model with a new relation",
"relations": [
"abc123",
"def456",
"xyz999"
]
}
I was hoping this would be trivial with a custom converter. The T
type is used as a placeholder since this is my main problem:
class RelationsConverter implements JsonConverter<Relation, T> {
const RelationsConverter();
@override
Relation fromJson(K json) => ...
@override
T toJson(Skill data) => ...
}
@freezed
class MyModel with _$MyModel {
const factory MyModel({
String name,
@RelationsConverter() List<Relation>? relations,
}) = _MyModel;
factory MyModel.fromJson(Map<String, Object?> json) => _$MyModelFromJson(json);
}
The problem here is that while jsonFrom
is passed a Map, toJson returns a String:
Relation fromJson(Map<String, dynamic> json) => Relation.fromJson(json);
String toJson(Relation relation) => relation.id;
However I need to pass a specific type for both to-and fromJson to JsonConverter:
class RelationsConverter implements JsonConverter<Relation, [Map or String]>
I neither can omit fromJson
(which I'd like to) because the interface forces me to implement both methods.
How can I solve this? I I could get around my custom transforming if the incoming data and solve this in a converter, this would also be nice.
it's a little late to answer the question but since i encountered a similar issue, i found a workaround to it using JsonConverter
for example, if you are converting a variable someBoolean bool -> string when sending data to the api and the api sends someBoolean as bool back then you would have bool->string while sending and bool->bool while receiving.
the json converter would look something like this: