Search code examples
flutterdartflutter-futurebuilderdynamic-function

how to use "snapshot.hasData" with Dynamic Future builder


I had a String type future method but I had to do some modifications to the code and I changed my future method to dynamic future and everysince the future builder never validate if snapshot has data


  late final Future myFuture;

 @override
  void initState() {
    myFuture =  getUserInfo();

    super.initState();
  }

Future  getUserInfo() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    bool check = preferences.containsKey('$userID,imageURL');
    if(check == true){
      userName = preferences.getString('$userID,name')?? "No name found";
      userWeight = preferences.getString('$userID,weight') ?? "no wight found";
      userHeight = preferences.getString('$userID,height') ?? "no Height found";
      userGender = preferences.getString('$userID,genderType') ?? "no gender Type found";
      birthDateInString = preferences.getString('$userID,dateOfBirth') ?? "no date  found";
      imageURL = preferences.getString('$userID,imageURL') ?? "no image  found";
    }else{
      await downloadValues();
    }


  }

..........

 Widget userValues(){
    return
      FutureBuilder(
        future: myFuture,
        builder: (BuildContext context, AsyncSnapshot snapshot){
          if(snapshot.connectionState == ConnectionState.waiting){
          return const CircularProgressIndicator();
          }
          else if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Center(
                child: Text(
                  '${snapshot.error} occurred',
                  style: const TextStyle(fontSize: 18),
                ),
              );
            }
            else if (snapshot.hasData){
              return Column(
                children: [
                  Container(

                  ),
                  Padding(
                    padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
                    child: ListTile(
                      title: Text("$userName",
                        textAlign: TextAlign.center,
                        style: GoogleFonts.mouseMemoirs(
                            fontSize: 30,
                            color: Colors.black
                        ),
                      ),
                    ),
                  ),

                ],
              );
            }
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      );
  }

In this case the future builder is always returning CircularProgressIndicator. However, if I change the condition from else if (snapshot.hasData) to just else { }, then the code will run properly but I dont think thats how it should be done.

Any suggestions?


Solution

  • @pskink is right. You should return a value (if you're using the returned value) or return nothing (like: return;) and set another value somewhere else and use this, which you are doing right now if I understood correctly.

    Edit: my mistake. snapshot.hasData checks if anything returned from the future. You should return a value from the Future in this case. Sorry about that.

    Future  getUserInfo() async{
        SharedPreferences preferences = await SharedPreferences.getInstance();
        bool check = preferences.containsKey('$userID,imageURL');
        if(check == true){
          userName = preferences.getString('$userID,name')?? "No name found";
          userWeight = preferences.getString('$userID,weight') ?? "no wight found";
          userHeight = preferences.getString('$userID,height') ?? "no Height found";
          userGender = preferences.getString('$userID,genderType') ?? "no gender Type found";
          birthDateInString = preferences.getString('$userID,dateOfBirth') ?? "no date  found";
          imageURL = preferences.getString('$userID,imageURL') ?? "no image  found";
        }else{
          await downloadValues();
        }
    
       return userName; // this should do the trick
      }