-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Sorry for the continuous streak of questions, I got hyped!
Using my repo from #6 as context, I now face a rather annoying issue regarding (I guess) ahead of compilation vs runtime types, when a modddel is exposed through a Riverpod provider cased Modddels in a union (in my case, the union modddels is exposed through a Riverpod AsyncNotifier, which wraps an AsyncValue<MapLayer> with MapLayer being the union of modddels: MapLayer.raster, MapLayer.vector and MapLayer.geojson).
My guess is that I’m not providing Riverpod with enough insight, but I did not manage to discover how.edit: wrong guessing 🙈
Here it is, explained by comments:
// [… imports … ]
class Map extends ConsumerWidget {
const Map({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final logger = ref.read(loggerProvider);
final provider = mapLayerControllerProvider(layerName: "some_raster_layer");
final rasterLayer = ref.watch(provider);
return rasterLayer.when(data: (layer) {
logger.d(layer);
// ==> layer exposed as a ValidRaster, which is expected, for it was created
// with MapLayer.raster(…) with valid attributes values;
// but this fails because Dart thinks it’s a MapLayer, which has no position attribute:
// logger.i(layer.position.value);
// ==> Hence doing a cumbersome type casting:
final l = layer as ValidRaster;
logger.i(l.position.value); // works fine now!
return Text("OK");
}, error: (e, _) {
logger.d(e);
return Text("KO");
}, loading: () {
logger.d("Loading…");
return Text("Loading…");
});
}
}Of course, the problem stays the same if I, say, mapValidity on layer within the widget (rather than within the controller/provider):
return rasterLayer.when(data: (layer) {
return layer.mapValidity(valid: (layer) {
logger.d(layer.runtimeType); // ValidRaster
// logger.i(layer.position.value); // Error: The getter 'position' isn’t defined for the type 'ValidMapLayer'.
logger.i((layer as ValidRaster).position.value); // works fine, for ValidRaster extends MapLayer
// with Raster, which has the attributes
return Text("Valid layer $layer");
}, invalid: (layer) {
logger.d(layer.runtimeType); // InvalidRaster
logger.d(layer.failures); // works fine; layer is seen as an InvalidMapLayer, though
return Text("Invalid layer $layer");
});
}, error: (e, _) {
logger.d(e);
return Text("KO");
}, loading: () {
logger.d("Loading…");
return Text("Loading…");
});