TextEditingController not updating upon input to TextField in Flutter

Advertisements

I have a CustomPasswordField widget which is supposed to take input via a TextEditingController. However, when I enter any input to this widget, its TextEditingController does not hold any value (when I tested it by printing its value to the terminal it keeps returning "").

My Code:

custom_passwordfield.dart

import 'package:flutter/material.dart';

import '../global_variables/global_variables.dart';

class CustomPasswordField extends StatefulWidget {
  CustomPasswordField({
    Key? key,
    required this.width,
    required this.height,
    required this.textEditingController,
    required this.hintText,
    required this.isObscured,
    required this.onChanged,
  }) : super(key: key);

  final double width;
  final double height;
  final TextEditingController textEditingController;
  final String hintText;
  bool isObscured;
  final Function(String)? onChanged;

  @override
  State<CustomPasswordField> createState() => _CustomPasswordFieldState();
}

class _CustomPasswordFieldState extends State<CustomPasswordField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width,
      height: widget.height,
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.grey,
          width: 0.25,
        ),
        borderRadius: const BorderRadius.all(Radius.circular(10)),
      ),
      child: Padding(
        padding: EdgeInsets.only(
          left: widget.width * 0.05,
          right: widget.width * 0.05,
        ),
        child: TextField(
          cursorColor: Colors.grey,
          obscureText: widget.isObscured,
          onChanged: widget.onChanged,
          style: globalTextStyle.copyWith(
              color: Colors.grey, fontSize: widget.width * 0.04),
          decoration: InputDecoration(
            border: InputBorder.none,
            hintText: widget.hintText,
            hintStyle: globalTextStyle.copyWith(
                color: Colors.grey, fontSize: widget.width * 0.04),
            suffixIcon: IconButton(
              onPressed: () {
                setState(() {
                  widget.isObscured = !widget.isObscured;
                });
              },
              icon: (widget.isObscured)
                  ? Icon(
                      Icons.visibility_outlined,
                      color: Colors.grey,
                      size: widget.width * 0.04,
                    )
                  : Icon(
                      Icons.visibility_off_rounded,
                      color: Colors.grey,
                      size: widget.width * 0.04,
                    ),
            ),
          ),
        ),
      ),
    );
  }
}

signup_screen.dart

import 'package:flutter/material.dart';
import 'package:musicart/global_variables/global_variables.dart';
import 'package:musicart/widgets/custom_passwordfield.dart';
import 'package:musicart/widgets/custom_textfield.dart';

class SignUpScreen extends StatefulWidget {
  const SignUpScreen({Key? key}) : super(key: key);

  @override
  State<SignUpScreen> createState() => _SignUpScreenState();
}

final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _confirmPasswordController =
    TextEditingController();

class _SignUpScreenState extends State<SignUpScreen> {
  @override
  Widget build(BuildContext context) {
    double? screenWidth = MediaQuery.of(context).size.width;
    double? screenHeight = MediaQuery.of(context).size.height;

    String passwordStatus = "Weak Password";
    int passwordStrength = 1;
    bool passwordsMatch = false;
    String passwordsMatchStatus = "Passwords do not match";
    String password = "";
    String confirmPassword = "";

    void getPasswordStatus(String pw) {
      if (pw.length >= 8) {
        setState(() {
          passwordStatus = "Strong Password";
          passwordStrength = 2;
        });
      } else if (pw.length >= 6 && pw.length <= 8) {
        setState(() {
          passwordStatus = "Weak Password";
          passwordStrength = 1;
        });
      }
    }

    bool doPasswordsMatch(String pw, String cpw) {
      if (pw == cpw) {
        return true;
      }
      return false;
    }

    return SafeArea(
      child: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              CustomTextField(
                width: screenWidth * 0.8,
                height: screenWidth * 0.8 / 6.8,
                textEditingController: _emailController,
                hintText: "Email..",
              ),
              SizedBox(
                height: screenHeight * 0.02,
              ),
              CustomPasswordField(
                width: screenWidth * 0.8,
                height: screenWidth * 0.8 / 6.8,
                textEditingController: _passwordController,
                hintText: "Password",
                isObscured: true,
                onChanged: (p0) {
                  setState(() {
                    password = p0;
                    getPasswordStatus(password);
                    print(
                        "$passwordStatus, $passwordStrength, ${_passwordController.text}, $password");
                  });
                },
              ),
              SizedBox(
                height: screenHeight * 0.01,
              ),
              Padding(
                padding: EdgeInsets.only(right: screenWidth * 0.1),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Text(
                      _passwordController.text,
                      style: globalTextStyle.copyWith(
                        fontSize: screenWidth * 0.02,
                        color: (passwordStrength == 2)
                            ? Colors.green
                            : Colors.orange,
                      ),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: screenHeight * 0.02,
              ),
              CustomPasswordField(
                width: screenWidth * 0.8,
                height: screenWidth * 0.8 / 6.8,
                textEditingController: _confirmPasswordController,
                hintText: "Confirm password",
                isObscured: true,
                onChanged: (p0) {
                  setState(() {
                    confirmPassword = p0;
                    passwordsMatch =
                        doPasswordsMatch(confirmPassword, password);
                    passwordsMatchStatus = (passwordsMatch)
                        ? "Passwords match"
                        : "Passwords do not match";
                    print(
                        "$p0, ${_passwordController.text}, $confirmPassword, $password, $passwordsMatchStatus, $passwordsMatch");
                  });
                },
              ),
              SizedBox(
                height: screenHeight * 0.01,
              ),
              Padding(
                padding: EdgeInsets.only(right: screenWidth * 0.1),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Text(
                      passwordsMatchStatus,
                      style: globalTextStyle.copyWith(
                        fontSize: screenWidth * 0.02,
                        color: (passwordsMatch) ? Colors.green : Colors.red,
                      ),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: screenHeight * 0.02,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

What is wrong in my code that prevents the TextEditingControllers for my widget to store input values to the textfields and how to solve the problem?

>Solution :

TextFiled is missing controller on CustomPasswordField class.

child: TextField(
  controller: widget.textEditingController,
  cursorColor: Colors.grey,
  obscureText: widget.isObscured,
  onChanged: widget.onChanged,
  style: globalTextStyle.copyWith(
      color: Colors.grey, fontSize: widget.width * 0.04),

Also it is better to move variables outside the build method on _SignUpScreenState

   String passwordStatus = "Weak Password";
    int passwordStrength = 1;
    bool passwordsMatch = false;
    String passwordsMatchStatus = "Passwords do not match";
    String password = "";
    String confirmPassword = "";

 @override
  Widget build(BuildContext context) {

Leave a ReplyCancel reply