excepion when using `MappingHook` on nullable fields: type `Null` is not a subtype of type `X` in type cast
Closed this issue · 3 comments
MohaAmiry commented
for the following code:
class LocationHook extends MappingHook{
@override
Location? afterDecode(Object? value) {
print(value);
if(value is! Location) return null;
return (value).address.isEmpty? null: value;
}
const LocationHook();
}
@MappableClass(hook: LocationHook())
class Location with LocationMappable{
final String address;
final String? details;
const Location(this.address, this.details);
}
@MappableClass()
class Person with PersonMappable{
final String name;
final Location? location;
const Person(this.name, this.location);
}
void main() async {
var map = {"name":"name","location":{"address":"","details":null}};
print(PersonMapper.fromMap(map));
}
Expected Result:
i'm expecting to change every Location object to null in case the address is empty.
Actual Result:
running the previous code will throw the following exception although the Person.location
is nullable:
MapperException: Failed to decode (Person).location(Location?): type 'Null' is not a subtype of type 'Location' in type cast
#0 InterfaceMapperBase.decoder (package:dart_mappable/src/mappers/interface_mapper.dart:141:42)
#1 ClassMapperBase.decoder (package:dart_mappable/src/mappers/class_mapper.dart:153:24)
#2 MapperBase.decodeValue (package:dart_mappable/src/mappers/mapper_base.dart:43:14)
#3 _MapperContainerBase.fromValue (package:dart_mappable/src/mapper_container.dart:369:21)
#4 DecodingUtil.$dec (package:dart_mappable/src/mapper_utils.dart:24:29)
#5 Field.decode (package:dart_mappable/src/mappers/interface_mapper.dart:86:19)
#6 DecodingData.dec (package:dart_mappable/src/mappers/interface_mapper.dart:100:26)
#7 PersonMapper._instantiate (package:lab/lab.mapper.dart:148:43)
#8 InterfaceMapperBase.decode (package:dart_mappable/src/mappers/interface_mapper.dart:153:25)
#9 ClassMapperBase.decode (package:dart_mappable/src/mappers/class_mapper.dart:176:18)
#10 InterfaceMapperBase.decoder (package:dart_mappable/src/mappers/interface_mapper.dart:138:18)
#11 ClassMapperBase.decoder (package:dart_mappable/src/mappers/class_mapper.dart:153:24)
#12 MapperBase.decodeValue (package:dart_mappable/src/mappers/mapper_base.dart:43:14)
#13 InterfaceMapperBase.decodeMap (package:dart_mappable/src/mappers/interface_mapper.dart:205:47)
#14 PersonMapper.fromMap (package:lab/lab.mapper.dart:155:32)
#15 main (package:lab/lab.dart:34:20)
#16 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#17 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
schultek commented
Yes applying a hook to a class will always expect the non-nullable type (Location). You can try instead applying the hook to the field, which will the work correctly with the nullable type (Location?).
So:
@MappableClass()
class Person with PersonMappable{
final String name;
@MappableField(hook: LocationHook())
final Location? location;
const Person(this.name, this.location);
}
MohaAmiry commented
so to achieve my goal "make every location null if the a specific condition is true", i must use the location hook everywhere i use the location object. right?
schultek commented
yes