I have a drop-down where I can select several items. I am using a StateNotifier because the logic is a little bit too complicated for a simple StateProvider. I have a model class with attributes I want to fill e.g.
Class ReportError {
Name;
Code;
Png;
...
}
So here is my problem:
@override
Widget build(BuildContext context) {
final selectedValue = ref.watch(fillErrorModelProvider).selectedTool; //here I watch at my state, here I think is my problem
return Stack(
children: [
Align(
//..Here is my drop-down on changed
onChanged: (value) {
ref.read(fillErrorModelProvider.notifier).setToolName(value!);
print(selectedValue); // and this is always one behind. So when I select cat, it says null, then I change to dog, it says cat.
},
),
//...
],
);
}
What am I doing wrong? According to the documentation I thought I have to do this Variable = ref.watch(provider) directly under the build method.
When I change the print statement to the ref.watch directly, everything works fine.
My provider stuff:
final fillErrorModelProvider = StateNotifierProvider<FillReportBugModelNotifier, ReportBugModel>((ref) {
return FillReportBugModelNotifier();
});
class FillReportBugModelNotifier extends StateNotifier<ReportBugModel> {
FillReportBugModelNotifier() : super(ReportBugModel());
void setToolName(String selectedTool) {
state = ReportBugModel().copyWith(selectedTool: selectedTool);
}
}
2
Answers
FYI: Idk what happened, but it works now after a night. Maybe the night fixed the issue :D But this approach must be correct, so idk what was wrong, I didn't change the code.
This is the timeline of what happened:
build
method is called. The value ofselectedValue
is nownull
. TheonChanged
callback is not called yet.onChanged
callback is called, executing 2 lines: 1) The one that callsetToolValue
that (I assume) modify the notifier state tovalue
(which is cat), and 2) the one that prints the currentselectedValue
. Since this happens in the same scope of the current build (which is the first build mentioned in step 1), and no other build call has happened yet, so the value ofselectedValue
isnull
.build
method again. This happens because you watched the provider by having aref.watch
call inside thebuild
method. Now the value ofselectedValue
is cat.onChanged
callback is called. The same thing happens as in step 2, in which the notifier state changed to dog, and theselectedValue
, which currently holds the value of cat, is printed.build
method is called again. Now the value ofselectedValue
is dog.