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.