Closed cliftonlabrum closed 1 year ago
can you paste the full stacktrace of when this happens? Might be a bug in watch_it
Here is the stack trace:
════════ Exception caught by widgets library ═══════════════════════════════════
The following _TypeError was thrown building MyApp(dirty):
Null check operator used on a null value
The relevant error-causing widget was
MyApp
main.dart:6
When the exception was thrown, this was the stack
#0 watchPropertyValue
watch_it.dart:156
#1 MyApp.build
main.dart:15
#2 StatelessElement.build
framework.dart:5367
#3 _GetItElement.build
elements.dart:20
#4 ComponentElement.performRebuild
framework.dart:5297
#5 Element.rebuild
framework.dart:5016
#6 ComponentElement._firstBuild
framework.dart:5279
#7 ComponentElement.mount
framework.dart:5273
#8 _GetItElement.mount
elements.dart:10
... Normal element mounting (27 frames)
#35 Element.inflateWidget
framework.dart:4182
#36 Element.updateChild
framework.dart:3707
#37 RenderObjectToWidgetElement._rebuild
binding.dart:1253
#38 RenderObjectToWidgetElement.mount
binding.dart:1222
#39 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure>
binding.dart:1169
#40 BuildOwner.buildScope
framework.dart:2719
#41 RenderObjectToWidgetAdapter.attachToRenderTree
binding.dart:1168
#42 WidgetsBinding.attachRootWidget
binding.dart:1001
#43 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure>
binding.dart:981
#47 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
(elided 3 frames from class _Timer and dart:async-patch)
════════════════════════════════════════════════════════════════════════════════
It looks like the crash is on line 156
of watch_it.dart
where you are force-unwrapping observedProperty
(which, in my case, is null
at the moment).
assert(observedProperty! is! Listenable, 'selectProperty returns a Listenable. Use watchIt instead');
Here is a simple project reproducing it:
import 'package:flutter/material.dart';
import 'package:watch_it/watch_it.dart';
void main() {
di.registerSingleton<Test>(Test());
runApp(const MyApp());
}
class MyApp extends StatelessWidget with WatchItMixin {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
//~~~
watchPropertyValue((Test x) => x.selectedThing);
//~~~
return MaterialApp(
title: 'Watch It Test',
home: Column(
children: [
Text('Testing: ${Test.to.selectedThing}'),
TextButton(
onPressed: () {
final thing = Thing(name: 'hi');
Test.to.selectedThing = thing;
},
child: const Text('Set'),
),
],
),
);
}
}
class Test with ChangeNotifier {
static Test get to => di<Test>();
Thing? _selectedThing;
Thing? get selectedThing => _selectedThing;
set selectedThing(Thing? value) {
_selectedThing = value;
notifyListeners();
}
}
class Thing {
String name;
Thing({
required this.name,
});
}
(As a side note, I use Test.to.selectedThing
in my widget instead of final thing = watchPropertyValue((Test x) => x.selectedThing);
because it makes reactive variables easier to find in my widget code. 😊)
Fixed in V1.0.0
The fix works great! Thank you! 😄
You found an important bug that might have impacted others, so thanks for the report and analysis Am 24. Aug. 2023, 19:47 +0200 schrieb Clifton Labrum @.***>:
The fix works great! Thank you! 😄 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you modified the open/close state.Message ID: @.***>
I have an optional
selectedFlight
property in a class like this:...but it crashes when I set up the property value watcher in a widget:
How can I watch a nullable property that won't be set until later?