Widget is not updated even if notifyListeners called
Opened this issue · 0 comments
In my app there is a page which needs to be refreshed if new data is received from cloud. I have implemented it like this:
class ViewEventPage extends StatelessWidget {
final String eventId;
const ViewEventPage({Key key, this.eventId}) : super(key: key);
@override
Widget build(BuildContext context) {
return ScopedModel<EventListViewModel>(
model: MainViewModel().eventList,
child: ScopedModelDescendant<EventListViewModel>(
builder: (context, child, eventList) {
final currentEventViewModel =
eventList.getEventViewModel(eventId);
return ScopedModel<EventViewModel>(
model: currentEventViewModel,
child: ScopedModelDescendant<EventViewModel>(
builder: (context, child, eventViewModel) {
return Scaffold(
key: ValueKey(eventViewModel.event.localHashCode),
appBar: _AppBar(eventViewModel),
body: _Body(eventViewModel));
},
),
);
},
),
);
...
}
Basic idea is that EventListViewModel
notifies listeners when any changes from cloud are received. Then we know that we need to refresh the EventViewModel
instance which we are listening too.
One of the child widgets of _Body
is a stateful widget:
class AttachmentsSection extends StatefulWidget {
final EventViewModel viewModel;
const AttachmentsSection({
Key key,
this.viewModel,
}) : super(key: key);
@override
_AttachmentsSectionState createState() => _AttachmentsSectionState();
}
class _AttachmentsSectionState extends State<AttachmentsSection> {
@override
void initState() {
super.initState();
// option 1: this does not work (except during initial build where it works ok)
widget.viewModel.listAttachments();
// option 2: this works
// scheduleMicrotask(() => widget.viewModel.listAttachments());
// option 3: this works too
// widget.viewModel.listAttachments().then((_) => setState(() => {}));
// option 4: issue gets fixed also if I wrap Build-method with
// ScopedModel<EventViewModel> + ScopedModelDescendant<EventViewModel>
}
...
}
In the above code listAttachments
is an async method which calls notifyListeners
on the EventViewModel
which should trigger building the whole page again.
So the main problem here is that I don't understand why the option 1 does not work (works normally during the initial build but after that it doesn't work). And what is the preferred fix?
Also I am not fully sure if the code in ViewEventPage.build
is valid usage of ScopedModel
because I am changing the EventViewModel instance (it may be different instance than on previous build). But at least it seems to work with options 2-4.
I added this issue for a possible documentation update, because at least in my opinion this is quite confusing.