skip to Main Content

I have a variable late Future<QuestionModel> question; and a function that fetches QuestionModel

fetchQuestion(){
    // Question model is initialised here
}

It is being used in build to display a UI

          FutureBuilder(
              future: question,
              builder: (context, snapshot) {
                if (snapshot.data == null) {
                  return LoadingWidget(
                    height: 200,
                    width: 200,
                  );
                }
                if (snapshot.hasError) {
                  return Text("Something went wrong");
                }

                QuestionModel question = snapshot.data as QuestionModel;
                return Container(),
                  );
                }
            ),

Which is working fine.

In the UI itself I have a button which sends data to backend and fetches new QuestionModel from Firestore. Which is also working fine.

Requirement: To Show loading screen after clicking a button and avoid reclicking till the new QuestionModel is fetched but I don’t want to create a separate isLoading variable for that.

I just want to reset the questionModel which was initialised earlier as questionModel = null and show loading screen by making use of futurebuilder itself as I already have LoadingWidget attached to my FutureBuilder.
But that is not possible as Future can’t be null with below error

A value of type 'Null' can't be assigned to a variable of type 'Future<QuestionModel>'.

EDIT 2:
In other words I want to uninitialize the future to trigger my Future builder to show loading Widget.

2

Answers


  1. try the demo here to understand more

    https://dartpad.dev/?id=3dadbc210baaf70d405b75e5389c7ba8


    you can use setState to rebuild the FutureBuilder.

    But there are behavior for FutureBuilder will not execute the future method when you define it as local state variable

    solution:

    • define the Future method not as state variable. you can put in on any file. for example in your helper.dart
    Future<String> apiCall() async {
      print("apiCall is executed...");
      await Future.delayed(const Duration(seconds: 3));
      return Future.value("${Random().nextInt(100)} update");
    }
    

    then in your FutureBuilder widget, use condition for ConnectionState.waiting,

    and every time you call setState the apiCall will executed

    FutureBuilder(
          future: localFuture,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(child: CircularProgressIndicator());
            } else {
              return Text("${snapshot.data}");
            }
          })
    

    ps: if you use snapshot.hasData , it will be true even the apiCall not finish yet. better to listern the connection state.

    Login or Signup to reply.
  2. Change declaration to this : late Future<QuestionModel>? question;

    Change your code to this :

    FutureBuilder(
                  future: question,
                  builder: (context, snapshot) {
                    if (snapshot.data == null) {
                      return LoadingWidget(
                        height: 200,
                        width: 200,
                      );
                    }
                    if (snapshot.hasError) {
                      return Text("Something went wrong");
                    }
    
                    QuestionModel? question = snapshot.data as QuestionModel;
                    return Container(),
                      );
                    }
                ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search