Home > Software engineering >  Flutter Dart: TextEditingController wont work when i shift to another file
Flutter Dart: TextEditingController wont work when i shift to another file

Time:03-06

I am very new to Dart, and coding in general. I have produced this code after watching tutorials on YouTube. For the most part, I have been able to troubleshoot most of my problems on my own, yet I cannot figure out my most recent errors. Here I made a TextEditingController on a page(Which worked fine BTW), and later I shifted to another page to make the code clean. But they stopped working.

import 'package:care_ls/model/userProfileModel.dart';
import 'package:care_ls/services/database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:care_ls/views/views.dart';
import 'package:care_ls/controllers/controllers.dart';

class ProfilePage extends StatelessWidget {
const ProfilePage({Key? key}) : super(key: key);

 @override
 Widget build(BuildContext context) {
  

return Scaffold(
  body: SafeArea(
    child: Column(
      children: [
        TextFormField(
          controller: profilePageTextControllers().fnameController,
          onChanged: (e)=> print(e),
          obscureText: false,
          decoration: const InputDecoration(
            hintText: 'First Name',
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Color(0xff2AA8A1),
                width: 1,
              ),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(4.0),
                topRight: Radius.circular(4.0),
              ),
            ),
            focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Color(0xff272361),
                width: 1,
              ),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(4.0),
                topRight: Radius.circular(4.0),
              ),
            ),
          ),
          //style: FlutterFlowTheme.of(context).bodyText1,
        ),
        TextFormField(
          controller: profilePageTextControllers().lnameController,
          obscureText: false,
          decoration: const InputDecoration(
            hintText: 'Second Name',
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Color(0xff2AA8A1),
                width: 1,
              ),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(4.0),
                topRight: Radius.circular(4.0),
              ),
            ),
            focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Color(0xff272361),
                width: 1,
              ),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(4.0),
                topRight: Radius.circular(4.0),
              ),
            ),
          ),
          //style: FlutterFlowTheme.of(context).bodyText1,
        ),
        
        ElevatedButton(
            onPressed: () async {
              final userprofile = UserProfileModel(
                  firstName: profilePageTextControllers().fnameController.text.trim(),
                  lastName: profilePageTextControllers().lnameController.text.trim(),
                  );

              await Database.addProfile(userprofile);
              profilePageTextControllers().fnameController.clear();
              profilePageTextControllers().lnameController.clear();
             
              print('Data Sent');
            },
            child: Text('Done')),
        ElevatedButton(
            onPressed: () => Get.to(HomePage()), child: Text('Back')),
      ],
    ),
  ),
);
}
}

Here is My controller that I move to another file

import 'package:flutter/material.dart';

class profilePageTextControllers {

TextEditingController fnameController = TextEditingController();
TextEditingController lnameController = TextEditingController();

 }

Can anyone help me in understanding what I did wrong?

CodePudding user response:

You have a silly mistake in here. When you use TextFormField you should use a global form key to handle the form. Try this code snippet

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

 @override
 State<ProfilePage> createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
final _key = GlobalKey<FormState>();

TextEditingController fnameController = TextEditingController();

TextEditingController lnameController = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
  body: SafeArea(
    child: Form(
      key: _key,
      child: Column(
        children: [
          TextFormField(
            controller: fnameController,
            onChanged: (e)=> print(e),
            obscureText: false,
            decoration: const InputDecoration(
              hintText: 'First Name',
              enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(
                  color: Color(0xff2AA8A1),
                  width: 1,
                ),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(4.0),
                  topRight: Radius.circular(4.0),
                ),
              ),
              focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(
                  color: Color(0xff272361),
                  width: 1,
                ),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(4.0),
                  topRight: Radius.circular(4.0),
                ),
              ),
            ),
            //style: FlutterFlowTheme.of(context).bodyText1,
          ),
          TextFormField(
            controller: lnameController,
            obscureText: false,
            decoration: const InputDecoration(
              hintText: 'Second Name',
              enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(
                  color: Color(0xff2AA8A1),
                  width: 1,
                ),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(4.0),
                  topRight: Radius.circular(4.0),
                ),
              ),
              focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(
                  color: Color(0xff272361),
                  width: 1,
                ),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(4.0),
                  topRight: Radius.circular(4.0),
                ),
              ),
            ),
            //style: FlutterFlowTheme.of(context).bodyText1,
          ),

          ElevatedButton(
              onPressed: () async {
                final userprofile = UserProfileModel(
                  firstName: fnameController.text.trim(),
                  lastName: lnameController.text.trim(),
                );

                await Database.addProfile(userprofile);
                fnameController.clear();
                lnameController.clear();

                print('Data Sent');
              },
              child: Text('Done')),
          ElevatedButton(
              onPressed: () => Get.to(HomePage()), child: Text('Back')),
        ],
      ),
    ),
  ),
);
}
}

CodePudding user response:

Your source of problem is you haven't learn about the state properly and then you're trying to build a project using a state management.

First, you need to learn about Stateless vs Stateful widget. Then, you need to learn State Management

Do not use succumb to the get package mentally by using that package in every corner of your code.


Now, let's dissect your code.

When you are using the following code:

controller: profilePageTextControllers().fnameController,

You're creating a new profilePageTextControllers object then accessing it fnameController property.

Then your other code:

controller: profilePageTextControllers().lnameController,

is creating another profilePageTextControllers object.

So, you have 2 differents object now.

Then you creating another objects in your onPressed button:

final userprofile = UserProfileModel(
                  firstName: profilePageTextControllers().fnameController.text.trim(),
                  lastName: profilePageTextControllers().lnameController.text.trim(),
                  );

So, you're trying to access fnameController and lnameController from different objects used in the TextFormField.

You can fix your code logic by creating a profilePageTextControllers variable then use it in your TextFormField. Something like this:

class ProfilePage extends StatelessWidget {
  const ProfilePage({Key? key}) : super(key: key);

  var _controllers = profilePageTextControllers();

  @override
  Widget build(BuildContext context) {
     return Scaffold(
       body : SafeArea(
         child: Column(
            children: [

               TextFormField(
                 controller: _controllers.fnameController,
                 ...
               ),

               TextFormField(
                 controller: _controllers.lnameController,
                 ...
               ),


                // Use _controllers in button onPressed too.
            ]
         )
       )
     );
             
  }
}

Or for the better solution, you can follow @saiful-islam answer by using StatefulWidget.

  • Related