1

I do have a lot of code that looks like this:

bool _somethingFromApiLoaded = false;
Something _somethingFromApi;

loadSomething() async {
  final something = await ServiceProvider.of(context).apiService.getSomething();
  setState(() => _somethingFromApi = something);
}

@override
Widget build(BuildContext context) {
  if (!_somethingFromApiLoaded) {
      loadSomething();
      _somethingFromApiLoaded = true;
  }
}

Note how I produce a lot of boilerplate code to ensure loadSomething is only called once.

I wonder if there isn't a lifecycle method to do so that I somehow misinterpret. I can't use initState because it does not have context.

shredding
  • 5,374
  • 3
  • 46
  • 77
  • Context is available everywhere in a Stateful widget. – gegobyte Apr 04 '20 at 18:44
  • there is solution here you can try. https://stackoverflow.com/questions/49457717/flutter-get-context-in-initstate-method – bingcheng45 Apr 04 '20 at 18:53
  • @gegobyte: It results in an error `dependOnInheritedWidgetOfExactType() or dependOnInheritedElement() was called before _MyClass.initState() completed.` @bingcheng45: Hm, that looks like even more boilerplate. – shredding Apr 04 '20 at 18:56

2 Answers2

3

I would try to a use a StatefulWidget and use initState() method.

That is the lifecycle you are referring to.

You should try to use a Future inside the initState()

  @override
  void initState() {
    super.initState(); // make sure this is called in the beggining

    // your code here runs only once

    Future.delayed(Duration.zero,() {
      _somethingFromApi = await ServiceProvider.of(context).apiService.getSomething();
    });

  }

As User gegobyte said, Context is available in the initState. But apparently can't be used for everything.

encubos
  • 2,915
  • 10
  • 19
0

You can use context in initState() by passing it to the widget:

class HomeScreen extends StatefulWidget {
  final BuildContext context;
  HomeScreen(this.context);

  @override
  State<StatefulWidget> createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _somethingFromApiLoaded = false;
  Something _somethingFromApi;

  loadSomething() async {
    final something = await ServiceProvider.of(widget.context).apiService.getSomething();
    setState(() => _somethingFromApi = something);
  }

  @override
  void initState() {
    super.initState();
    if (!_somethingFromApiLoaded) {
      loadSomething();
      _somethingFromApiLoaded = true;
    }
  }
}
oblomov
  • 426
  • 6
  • 9