First letter gets lost if I invoke 'setState' in 'onChange' of a TextField

158

I realized that by using Focus, I can achieve similar result:

            child: TextField(
              controller: passwordController,
              obscureText: true,
              decoration: InputDecoration(
                labelText:"Password",
              ),
              onSubmitted: (s) {
                submit();
              },
            ),
            onFocusChange: (hasFocus) {
              if (hasFocus) {
                if (this._error.isNotEmpty) {
                  setState(() {
                    this._error = "";
                  });
                }}
            }),```


Share:
158
moka67
Author by

moka67

Updated on November 21, 2022

Comments

  • moka67
    moka67 over 1 year

    I have 2 textfields, Email and Password. After email is entered and the user goes to password field, I display default message 'Password must not be empty' below the Password Textfield widget. I want to hide this message when the user starts typing the password.

    NOTE : I have to use Textfield widget. Here is the code:

    @override
    Widget build(BuildContext context) {
    final TextEditingController emailController =
        new TextEditingController(text: this._email);
    final TextEditingController passwordController =
        new TextEditingController();
    
    final submit = () async {
      try {
        FauiUser user = await fauiSignInUser(
          apiKey: this.widget.firebaseApiKey,
          email: emailController.text,
          password: passwordController.text,
        );
      } catch (e) {
        this.setState(() {
          this._error = FauiError.exceptionToUiMessage(e);
          //after typing email, when user presses <enter> or clicks in the Password field, the default message "Password must not be empty"
          //is assigned to this._error and displayed below Password Textfield widget
          this._email = emailController.text;
        });
      }
    };
    
    return Column(
        children: <Widget>[
          TextField(
            controller: emailController,
            autofocus: true,
            decoration: InputDecoration(
              labelText: 'EMail',
            ),
            onSubmitted: (s) {
              submit();
            },
          ),
          TextField(
            controller: passwordController,
            obscureText: true,
            decoration: InputDecoration(
              labelText: 'Password',
            ),
            onSubmitted: (s) {
              submit();
            },
          ),
          RaisedButton(
            child: Text('Sign In'),
            onPressed: submit,
          ),
        ]);
    

    } }

    I tried adding the following code :

    onChanged: (s) {
                if (this._error.isNotEmpty) {
                  setState(() {
                    this._error = "";
                  }); //to hide the default message below Password widget
                }
              },
    

    This rebuilds the screen and the message goes away but passwordController.text gets initialized and the first character entered before the rebuild gets lost in that process( e.g. if the user types “hello”, the value becomes ”ello”). How can I fix the code so that the first letter is not lost?