Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access provider value in Init state

Tags:

flutter

How do I access the value in a provider model from the init function or a workaround?

Basically, when my App loads, I save some value in a provider model.

One value is a search variable. Then I am redirected to a loading page where I need this value to get the data and render a list.

I am retrieving the data in the init method.

-- My Main function

void main() {
  runApp(
   Provider<UserModel>(
      builder: (_) => UserModel(),
      child: Jobs(),
    ),
  ); //added
}

This is a snippet of my Jobs page

case '/main':
   return MaterialPageRoute(
      builder: (_) => JobsHomePage(title: "jobs"));
   break;

This is list page that displays this list --- JobsHomePage()

void initState() {
    searchVal = Provider.of<UserModel>(context).searchVal;
    jb =load(searchVal);
}

Then I have a builder method that iterates thru 'jb' and prints the value

The error I am getting is inherited error

flutter: When an inherited widget changes, for example, if the value of Theme.of() changes, it's dependent

Thanks for your help... I did not post the entire code because it is very long and I get some "all code" error in the stack.

like image 955
user2570135 Avatar asked Aug 18 '19 17:08

user2570135


2 Answers

The accepted answer by Mikhail is fine if you don't need to update the widget again after performing some task in the didChangeDependencies method. (Which is not the case most of the time.)

But it will not work if you need to notify the listeners after performing the task.

The context is accessible in initState. You need to add the argument listen: false to the Provider.

The docs say

listen: false is necessary to be able to call Provider.of inside [State.initState] or the create method of providers like so: ...

  @override
  void initState() {
    super.initState();
    final _store = Provider.of<RecorderStore>(context, listen: false);
  }

Now as to why overriding didChangeDependencies is not a good idea:

In the docs it says

For example, if the previous call to build referenced an InheritedWidget that later changed, the framework would call this method to notify this object about the change.

Therefore when you use ChangeNotifierProvider for example, when you call notifyListeners() that will call the didChangeDependencies method.

So when you call notifyListeners through didChangeDependencies it will lead to an infinite loop.

Or even if you don't call notifyListeners explicitly, whenever the didChangeDepencies method is called, the code is executed multiple times.

So better to use listen: false in the initState to ensure that the code is executed only once.

like image 145
Phani Rithvij Avatar answered Dec 26 '22 14:12

Phani Rithvij


You can't access context in initState, but you can access it in didChangeDependencies.
According to offical docs it's called right after initState and it can use context, so it can call Provider.of<T>(context)

like image 38
Mikhail Ponkin Avatar answered Dec 26 '22 15:12

Mikhail Ponkin