Reputation: 4199
I'm calling one of the ChangeNotifier
functions from an initState()
method and the notifyListener()
call inside the function is throwing
setState() or markNeedsBuild() called during build.
exception
void initState(){
Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0);
super.initState();
}
class MessengerRepository with ChangeNotifier {
int unreadCount;
void setUnreadCount(int value){
unreadCount = value;
notifyListeners();
}
I need to call the notifyListener()
inside setUnreadCount()
as I'm calling the setUnreadCount()
function in multiple places during the execution. So can't remove the notifyListener()
only inside initState()
.
Using provider
version 4.0.4
Upvotes: 3
Views: 4201
Reputation: 4199
The cause for this issue as mentioned in the log message is that the function inside initState()
is requesting a rebuild through notifyListener()
(the same will happen if we use setState()
as well) even before the first build is completed.
The solution is to add a addPostFrameCallback
and execute the rebuilding function inside it so that it will execute only after the first building of the widget
void initState() {
super.initState();
WidgetsBinding
.instance
.addPostFrameCallback((_){
Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0);
}
);
}
Upvotes: 7
Reputation: 2839
You can move Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0);
from intState
to didChangeDependecies
then it'll be called only once page finishes build process.
Or by this way :(less elegant)
void setUnreadCount(int value, {bool shouldUpdate: true}){
unreadCount = value;
if(shouldUpdate) notifyListeners();
Then
void initState(){
Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0, shouldUpdate:false);
super.initState();
}
When you call it in initState
, if the build method finishes before all your variables are (re)assigned they'll not be updated until you call setState
or notifyListeners
Upvotes: 0