I am calling initial method to load data from API using initState. But it is resulting me an error. Here is error:
Unhandled Exception: inheritFromWidgetOfExactT
You need to call _getCategories
after initState
has completed.
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
this._getCategories();
});
// Could do this in one line: Future.delayed(Duration.zero, this._getCategories);
}
Also, you could do this on a different way, using addPostFrameCallback like showed in another answers.
Use the didChangeDependencies method which gets called after initState.
For your example:
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
this._getCategories();
}
void _getCategories() async {
// Omitted for brevity
// ...
}
The best solution i think is use the context from the Widget build. And paste the method _getCategories(context) after the build with the context from the tree. So there is no problem with the widget tree.
Adding a frame callback might be better than using Future.delayed
with a zero duration - it's more explicit and clear as to what is happening, and this kind of situation is what frame callback was designed for:
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
_getCategories();
});
}
There are many ways to solve this problem, override initState
method:
@override
void initState() {
super.initState();
// Use any of the below code here.
}
Using SchedulerBinding
mixin:
SchedulerBinding.instance.addPostFrameCallback((_) {
// Call your function
});
Using Future
class:
Future(() {
// Call your function
});
Using Timer
class:
Timer(() {
// Call your function
});
an alternative is to put it inside PostFrameCallback
which is between initState
and Build
so we can be sure that the initState
is already finished.
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
super.initState();
}
getData() async {
}