Calling scopedModel from initState in flutter

I stumbled upon the following solution:

In the State Class of my StatefulWidget I do:

@override
void initState() {
  super.initState();
  // and here...
  MyModel model = ScopedModel.of(context);
  // now I can do with the model whatever I need to do:
  Text someVar = model.initialText;
  model.getValuesFromSomewhere();
  // and so on
}

This, in my opinion, is the easiest way of solving the problem as stated by the original Question.


I think you've a slight misunderstanding about the point of ScopedModel and ScopedModelDescendant. The basic idea of how these should work is that the ScopedModel is created with a valid model which can then be used in other parts of the app.

However, the ScopedModelDescendant should be used within the build() function of a one of your widgets and be part of the widget tree as well. The reason your fetch methods aren't being called is that it isn't in the widget tree so the build function will never be called.

I would recommend instead moving the fetch methods out of the model and into some other class (maybe call it a communicator or controller or something). Next, I'd make it so that the model is instantiated as the result of an asynchronous call from that controller.

And finally, rather than instantiating an invalid model then changing the model once the data has been fetched, I'd recommend using a FutureBuilder - this way you have control over what to build based on whether the future is underway, successful, or failed.

So that will look something like this (pseudo-code).

StatefulWidget (MyApp or whatever you call it)
  build =>
     FutureBuilder(<fetch model data>, ...)
       (if done)
          ScopedModel<MainModel>
             .... (whatever your code has here)
               ScopedModelDescendant<MainModel>
                  (build using the model)             
       (if not done)
          Loading.... (if needed)

If you absolutely want your model to always be there, I'd still recommend doing the fetching in the top stateful widget and simply changing which model you pass in below it rather than modifying the existing model once the data is loaded.


this is my solution i hope it help

@override
  void initState() {
    super.initState();
    User user = ScopedModel.of(this.context);
    _controllerFirstName.text = user.userData['first_name'];
    _controllerLastName.text = user.userData['last_name'];
    }