Home > Blockchain >  Flutter Failed assertion: 'initialValue == null || controller == null': is not true
Flutter Failed assertion: 'initialValue == null || controller == null': is not true

Time:05-30

I am trying to fetch data entered in firestore to my TextFormField in order to make it as a profile updating section but while doing so I am facing this error Failed assertion: line 150 pos 15: 'initialValue == null || controller == null': is not true. I am unfamiliar with it can anyone please guide me where I am making mistake how can I resolve it? Also is its the correct approach I am making profile updating section. User will first enter the data, it will be empty by default and when the user will again come back to this screen the user should be shown the previous saved data that's exactly what I want.

Here's my code:

 final TextEditingController _peopletohangoutwithController =
      TextEditingController();// Controller 

// rest of the code

 FutureBuilder<DocumentSnapshot>(
            future: FirebaseFirestore.instance
                .collection("userpreferences")
                .doc(FirebaseAuth.instance.currentUser!.uid)
                .get(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                print(snapshot.hasData);
                print(snapshot.data!["peopletohangoutwith"]);
              }
              return Column(
                children: [
                  const SizedBox(
                    height: 50,
                  ),
                  Row(
                    children: [
                      Align(
                        alignment: Alignment.topLeft,
                        child: DelayedDisplay(
                            delay: const Duration(seconds: 1),
                            child: Padding(
                              padding: const EdgeInsets.only(left: 10),
                              child: IconButton(
                                icon: const Icon(
                                  Icons.arrow_back_ios,
                                  color: Colors.white,
                                ),
                                onPressed: () {
                                  Navigator.of(context).pop();
                                },
                              ),
                            )),
                      ),
                      const Align(
                        alignment: Alignment.topCenter,
                        child: DelayedDisplay(
                          delay: Duration(seconds: 1),
                          child: Text(
                            "Hang out with",
                            style: TextStyle(
                                fontSize: 26,
                                color: Colors.white,
                                fontFamily: "ProductSans",
                                fontWeight: FontWeight.bold),
                          ),
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(
                    height: 50,
                  ),
                  const DelayedDisplay(
                    delay: Duration(seconds: 2),
                    child: Center(
                      child: Padding(
                        padding: EdgeInsets.only(left: 10, right: 10),
                        child: Text(
                          "What type of people you want to hang out with",
                          style: TextStyle(
                              fontSize: 20,
                              color: Colors.white,
                              fontFamily: "ProductSans",
                              fontWeight: FontWeight.bold),
                        ),
                      ),
                    ),
                  ),
                  const SizedBox(
                    height: 50,
                  ),
                  DelayedDisplay(
                    delay: const Duration(seconds: 2),
                    child: Padding(
                      padding: const EdgeInsets.only(left: 30, right: 30),
                      child: TextFormField(
                          initialValue: snapshot.data!["peopletohangoutwith"],
                          controller: _peopletohangoutwithController,
                          maxLines: 10,
                          decoration: InputDecoration(
                            hintText: "Write in as detail as possible",
                            fillColor: Colors.white,
                            filled: true,
                            focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(0),
                              borderSide: const BorderSide(
                                color: Colors.white,
                              ),
                            ),
                            enabledBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(0),
                              borderSide: const BorderSide(
                                color: Colors.white,
                                width: 2.0,
                              ),
                            ),
                          )),
                    ),
                  ),
                  const SizedBox(
                    height: 100,
                  ),
                  DelayedDisplay(
                    delay: const Duration(seconds: 2),
                    child: Center(
                      child: FloatingActionButton.extended(
                        label: const Text('Save'),
                        backgroundColor: const Color(0xFF2A3B6A),
                        icon: const Icon(
                          Icons.save_as_outlined,
                          size: 24.0,
                        ),
                        onPressed: () async {
                          if (_peopletohangoutwithController.text.isEmpty) {
                            Get.snackbar(
                              "Error",
                              "Please explain your preference",
                              colorText: Colors.white,
                            );
                          } else {
                            FirebaseFirestore.instance
                                .collection("userpreferences")
                                .doc(FirebaseAuth.instance.currentUser!.uid)
                                .set({
                              "peopletohangoutwith":
                                  _peopletohangoutwithController.text,
                            });
                          }
                        },
                      ),
                    ),
                  ),
                ],
              );
            },
          ),

CodePudding user response:

Only one of the TextFormField's initialValue or controller can be used.

Use TextEditingController with initial value:

final controller = TextEditingController('the initial value');

CodePudding user response:

How bout you fetch the user data before going to the edit page.. Pass the data to the page in a constructor and enter the data in the text editing controller in init state.

EDIT: Sorry. Didn't knoqw you were a beginner.

Let's assume you're getting your data from some database eg Firebase. Ensure you have a usermodel. Models make data so much easier to manage. Soo,,

    class UserModel{
    String _userName;
    String _tikTok;

String get userName => _userName;
String get tiktok => _tikTok;

UserModel.fromSnapshot(DocumentSnapshot snapshot){
_userName = snapshot.data()["userName"];
_tikTok = snapshot.data()["tikTok"];
}
    }

This userModel can be used to propagate the profile page. Eg, if you got the data from firestore using streamBuilder, the builder would be sth like

(context, snapshot){
if(!snapshot.hasData}{
return LoadingWidget();
}else{
UserModel userModel = UserModel.fromSnapshot(snapshot.data);

return Scaffold(body: blah blah Text(userModel.userName) `and so forth`

I lost track of my brackets there, but you get the point.

Send the userModel to the next page via constructors, and initiate the data in initstate. Coz init state is the first function executed the moment the page loads. Even before it starts building widgets.

This is the code for the edit page.

class EditProfilePage extends StatefulWidget {
  final UserModel userModel;
  EditProfilePage({
    Key key,
    @required this.userModel,
  }) : super(key: key);

  @override
  State<EditProfilePage> createState() => _EditProfilePageState();
}

class _EditProfilePageState extends State<EditProfilePage> {
  TextEditingController nameController;
  TextEditingController tiktokAccountController;

  @override
  void initState() {
    super.initState();

    if (widget.userModel != null) {
      nameController = TextEditingController(
        text: widget.userModel.userName,
      );

      tiktokAccountController = TextEditingController(
        text: widget.userModel.tiktok,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: nameController,
          decoration: InputDecoration(
            hintText: "Username",
          ),
        ),
        SizedBox(
          height: 10,
        ),
        TextField(
          controller: tiktokAccountController,
          decoration: InputDecoration(
            hintText: "Tik Tok Username",
          ),
   

     ),
      ],
    );
  }
}

So, when you're going to the edit page from the profile page, you would call Navigator.of(context).push(EditBlahBlah(userModel: userModel,),)

Where userModel is the userModel you're viewing on the profile page. I hope that helps.

  • Related