Mohammed Hamdan
Mohammed Hamdan

Reputation: 1355

How can i call my provider model into initState method

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

Answers (5)

dingo
dingo

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

Jeex
Jeex

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

Zhar
Zhar

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

IonicFireBaseApp
IonicFireBaseApp

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

Javad Zobeidi
Javad Zobeidi

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

Related Questions