Home > Back-end >  FutureBuilder not working in OnTap() of GestureDetector
FutureBuilder not working in OnTap() of GestureDetector

Time:10-02

Upon user registration, I wish to call my database at Firebase to check that the email is unique. If it is not, I wish to show some form of an error message to the user.

However, for some reason the build method of my FutureBuilder is not called at all and none of my widgets in the submit() function are shown:

final usersRef = Firestore.instance.collection("users");

class _CreateAccountWithEmailState extends State<CreateAccountWithEmail> {
  Future<QuerySnapshot> existingUserWithEmail;

  emailExists(String email) {
    Future<QuerySnapshot> existingUserWithEmailFromDb =
        usersRef.where("email", isEqualTo: email).getDocuments();
    setState(() {
      existingUserWithEmail = existingUserWithEmailFromDb;
    });
  }


  Widget build(BuildContext context) {
    return Scaffold(
        appBar: header(context, titleText: "Complete your profile"),
        body: ListView(children: [
          ....
          Padding(
            padding: EdgeInsets.only(top: topPadding),
            child: Center(
              child: GestureDetector(
                onTap: () =>
                    {submit(context, context.read<UserSignupForm>().email)},
                child: Container(
                    height: 50.0,
                    width: 350.0,
                    decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius: BorderRadius.circular(7.0)),
                    child: Center(
                        child: Text(
                      "Save",
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold),
                    ))),
              ),
            ),
          )
        ]));
  }

  Widget submit(BuildContext context, String email) {
    return FutureBuilder(
        future: emailExists(email),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: Text('Please wait its loading...'));
          } else {
            if (snapshot.hasError)
              return Center(child: Text('Error: ${snapshot.error}'));
            else
              return Center(
                  child: new Text(
                      'Test: ${snapshot.data}'));
          }
        });
  }
}

Via debugging, I found that the future in the FutureBuilder is called, but not the builder. Any ideas please?

CodePudding user response:

Just remove => from GestureDetector onTap

Edited I hope will be got the idea how to solve it

final usersRef = Firestore.instance.collection("users");

class _CreateAccountWithEmailState extends State<CreateAccountWithEmail> {
  Future<QuerySnapshot> existingUserWithEmail;

  emailExists(String email) {
    Future<QuerySnapshot> existingUserWithEmailFromDb =
        usersRef.where("email", isEqualTo: email).getDocuments();
    setState(() {
      existingUserWithEmail = existingUserWithEmailFromDb;
    });
  }


  Widget build(BuildContext context) {
    return Scaffold(
        appBar: header(context, titleText: "Complete your profile"),
        body: ListView(children: [
          ....
          Padding(
            padding: EdgeInsets.only(top: topPadding),
            child: Center(
              child: GestureDetector(
                onTap: ()
                    {emailExists(context.read<UserSignupForm>().email);},
                child: Container(
                    height: 50.0,
                    width: 350.0,
                    decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius: BorderRadius.circular(7.0)),
                    child: Center(
                        child: Text(
                      "Save",
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold),
                    ))),
              ),
            ),
          ),
   // here show your data
          Text('Test: ${existingUserWithEmail?.data}')
        ]));
  }

CodePudding user response:

Okay, so basically calling submit function which returns FutureBuilder actually makes no sense because it has a return type of Widget. I don't actually quite fully know what you are wanting to accomplish here. But here's one solution to show the user if the user exists with the email already.

final usersRef = Firestore.instance.collection("users");

class _CreateAccountWithEmailState extends State<CreateAccountWithEmail> {
  bool? userExistsAlready;
  bool isBusy = false;

  Future<void> emailExists(String email) {
    setState(() {
      isBusy = true;
    });
    final getDocs = await usersRef.where("email", isEqualTo: email).get();
    setState(() {
      userExistsAlready = getDocs.docs.isNotEmpty;
      isBusy = false;
    });
  }


  Widget build(BuildContext context) {
    return Scaffold(
        appBar: header(context, titleText: "Complete your profile"),
        body: ListView(children: [
          ....
          Padding(
            padding: EdgeInsets.only(top: topPadding),
            child: Center(
              child: isBusy 
             ? CircularProgressIndicator() 
             : GestureDetector(
                onTap: ()
                    => emailExists(context.read<UserSignupForm>().email),
                child: Container(
                    height: 50.0,
                    width: 350.0,
                    decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius: BorderRadius.circular(7.0)),
                    child: Center(
                        child: Text(
                      "Save",
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold),
                    ),
                  )
                ),
              ),
            ),
          ),
          userExistsAlready == null ? SizedBox.shrink() :
          Text('User Exists Already: ${userExistsAlready}')
        ],
      ),
    );
  }
  • Related