Reputation: 1355
i have several widgets use my provider as a condition , and i need one call to access my provider to whole widget from init state instead of wrapping every widget into my provider and it's consumer
this is my provider
class ProviderForFiltter extends ChangeNotifier {
bool isFiltterrr = true ;
bool get isFiltter => isFiltterrr;
void changeStatus(bool status){
isFiltterrr = status;
notifyListeners();
}
}
this is my main.dart
class Myproject extends StatefulWidget {
const Myproject ({Key? key}) : super(key: key);
@override
_Myproject State createState() => _Myproject State();
}
class _Myproject State extends State<Myproject > {
@override
Widget build(BuildContext context) {
return
Provider(
create: (BuildContext context) {
return ProviderForFiltter();
},
child: const MaterialApp(
debugShowCheckedModeBanner: false,
home: WelcomeScreen()
),
),
);
}
}
this is my Stful
Widget
ProviderForFiltter? isF ;
@override
void initState() {
super.initState();
// i tried this but it always give me errors that is isF null value
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
isF = context.read<ProviderForFiltter>();
});
// also itried this but it don't work
isF = Provider.of<ProviderForFiltter>(context, listen: false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Text('change'),
)
}
}
in the fact i need to use it's bool value as condition into Consumer and change it
i hope any help guys
Upvotes: 4
Views: 4027
Reputation: 906
There are multiple ways to deal with this.
The first option (which I use) is to add a Post Frame Callback like so:
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
aProvider = Provider.of< aProvider >(context, listen: false);
});
Alternatively, you could override the didChangeDependencies method to get the provider value once initState has been called - remembering to set the listen value to false.
Upvotes: 1
Reputation: 306
You can use a different method called didChangeDependencies
to get the value from the provider after the initState
method is called. Also, make sure to set the listen
value to false
.
@override
void didChangeDependencies() {
super.didChangeDependencies();
final filtterData = Provider.of<ProviderForFiltter>(context, listen: false);
}
Upvotes: 0
Reputation: 3530
I was facing the same issue and regarding the documentation of provider this should be the answer.
"This likely happens because you are modifying the ChangeNotifier from one of its descendants while the widget tree is building."
In my case i am calling an http api async where the future is stored inside the notifier. So i have to update like this and it is working.
initState() {
super.initState();
Future.microtask(() =>
context.read<MyNotifier>().fetchSomething(someValue);
);
}
The best way is to use like this (when there's no "external parameter".
class MyNotifier with ChangeNotifier {
MyNotifier() {
_fetchSomething();
}
Future<void> _fetchSomething() async {}
}
source : https://pub.dev/packages/provider
Upvotes: 0
Reputation: 1230
providers need context, in order to access it for one time you should override didChangeDependencies
@override
void didChangeDependencies() {
super.didChangeDependencies();
///access provider here and update your state if needed,
///this will be called one time just before the build method
**isF = Provider.of<ProviderForFiltter>(context, listen: false);**
}
Upvotes: 0
Reputation: 191
is better don't do use Provider in initState, but you can use Future.delayed because you need context
@override
void initState() {
super.initState();
// i tried this but it always give me errors that is isF null value
Future.delayed(Duration(seconds: 1), () {
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
isF = context.read<ProviderForFiltter>();
});
// also itried this but it don't work
isF = Provider.of<ProviderForFiltter>(context, listen: false);
});
}
Upvotes: 0