1

I was trying to call APIs that need to be loaded the first time the page is built. So I used FutureBuilder and written an initState call. Every page works fine but only on one page, I faced an issue with context. Then I understood about didChangeDependencies. Which is the correct way to call APIs from another class (that need to access the current widget context too). Where should I call calculatorFuture = getParkingAreaList(); in initState() or didChangeDependencies().

String TAG = "CalculatorPage";

class CalculatorPage extends StatefulWidget {
  const CalculatorPage({
    Key key,
  }) : super(key: key);

  @override
  _CalculatorPageState createState() => _CalculatorPageState();
}
    class _CalculatorPageState extends State<CalculatorPage> {
      Future calculatorFuture;
    
     @override
      void initState() {
        super.initState();
      }
    
    
      @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        calculatorFuture = getParkingAreaList();
      }
    
    Future<bool> apiCallHere() async {
        print('apiCallHere');
        String lang = getCurrentLanguage(context);
        print('going to call res');
        var res = await HttpHandler.apiCallFromHttpHanlderClass(context);
        if (res == null) {
          print('res is null');
          showToast(LanguageLocalization.of(context).getTranslatedValue('generic_failure_message'));
          return false;
        }
        print(res);
        if(res["STATUS_CODE"] == 1) {
          print('apiCallHere status code = 1');
          apiData = res['someData'];
          return true;
        }
        else {
          print('apiCallHere status code !=1');
          return false;
        }
      }
    
    
      @override
      Widget build(BuildContext context) {
        print(TAG);
        return Scaffold(
            appBar: commonAppBar(context: context, title: 'calculator'),
            body: FutureBuilder(
              future: calculatorFuture,
              builder: (context, snapshot) {
                print(snapshot);
                if (snapshot.hasError || (snapshot.hasData && !snapshot.data)) {
                  print('has error');
                  print(snapshot.hasError ? snapshot.error : "unable to load data");
                  return unableToLoadView(context);
                } else if (snapshot.hasData && snapshot.data) {
                  print('completed future');
                  return Container(
                      margin: commonPagePadding,
                      child: ListView(
                        children: <Widget>[
                          //some widget that deals with apiData
                        ],
                      )
                  );
                } else {
                  print('loading');
                return showLoaderWidget(context);
                }
              },
            )
        );
    }
    }
Ameena Shafeer
  • 626
  • 3
  • 18
  • ameena call future function in didsomechange but use future key word like i mention in my answer and also await your function i give it example in answer it will be helpful for you. – Muhammad Arbaz Zafar May 25 '21 at 19:23

2 Answers2

0

you can call future function in didchangedependenci changing like that

@override
     Future <void> didChangeDependencies() async{
        super.didChangeDependencies();
        calculatorFuture = await getParkingAreaList();
      }
0

If you want to call the API once when a page loads up just place the future inside initState like the example below.

@override
  void initState() {
    super.initState();
    calculatorFuture = getParkingAreaList();
  }
techwithsam
  • 285
  • 3
  • 7