I have a scopedModel class where I fetch data into it. The thing is that I'm not being able to render this data from InitState method using my scoped model where I have all my api requests. The method is being called but the inside callings are not, so my initial state of the page is not properly shown.
void initState() {
print("Check initState");
super.initState();
ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget child, MainModel model) {
print("Get into the scoped model");
model.fecthCars();
model.fecthCities();
model.fecthBuys(model.getUserDto.token);
print(model.getBuys().length);
return;
});
}
None of the fetches(Api requests) get called. And the scopedModel returns a widget. I need this to be updated the first time I get into the manager and that's it. No need to call it again. Is this possible? or should I hardcode my api requests in each file I need?
UPDATE
If you have your scoped model class set up already you can set a Future like this inside of it
mixin MyModel on Model {
Future<TypeToReturn> methodName(String param) async {
Uri uri = new Uri.http('serverUrl', 'api/call');
return await http.get(uri).then((http.Response response) {
final List<dynamic> myResponse= json.decode(response.body);
return myResponse;
}).catchError((error) {
print(error);
});
}
}
Aftermards you can set up your FutureBuilder
Widget _buildBody(BuildContext context, MainModel model) {
return FutureBuilder(
future: model.methodName(someString), //This is the method name above
builder: (context, AsyncSnapshot<TypeToReturn> snapshot) { //type u return
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
if (snapshot.data.length == 0)
return Center(
child: Text(
"No Data Found",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
),
),
);
return (create your own widget with the data inside the snapshot)
}
},
);
}
Hope this clarify things a little bit more on how I did it.
In Flutter this can be done using a stateful widget and calling your code in the initState function. What if you want to call it from a stateless widget? Well, that's possible too. Use a stateful widget as a your root widget that you can provide a callback function too to execute your startup logic.
How do you call a function before building in Flutter? Timer. run(() => yourFunc(context));
3. initState() This is the first method called when the widget is created (after the class constructor, of course.) initState is called once and only once.
initializing a controller should be a one-time operation; if you do it on a StatelessWidget's build method, it will be triggered every time this widget is rebuilt. If you do it on a StatefulWidget's initState, it will only be called once, when this object is inserted into the tree when the State is initialized.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With