Hi! I'm building a receipt tracking component to an app which uploads data to Firebase but somehow the image file gives error after cropping [closed] - flutter

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
Improve this question
I'm using a form to collect data to be stored to Firebase. Along with the form is a Image to be captured from the camera / gallery as well. Currently I get 3x errors which I get stuck with.
on the Crop 'if' statement:
if (croppedImage != null) {
setState(() {
imageFile = File(croppedImage.path); //<----------- Error: the Argument Type String cant be //assigned to parameter type List<object>
});
}
}
await ref.putFile(imageFile!); //<----------- Error: The argument File (where is defined in... then a //location path... cant be assigned to a parament type File.
child: imageFile == null
? const Icon(
Icons.camera_enhance_sharp,
color: Colors.black,
size: 30,
)
: Image.file(
imageFile!, //<------------------Error The argument //File (Whrer is defined in... then a location path... cant be assisgned to a parament type File.
fit: BoxFit.fill,
),
Here is the full code structure:
class UploadSlips2 extends StatefulWidget {
const UploadSlips2({super.key});
#override
State<UploadSlips2> createState() => _UploadSlips2State();
}
class _UploadSlips2State extends State<UploadSlips2> {
final TextEditingController _slipCatagoriesController =
TextEditingController(text: 'Transaction Type');
final TextEditingController _projectListController =
TextEditingController(text: 'Select Project');
final TextEditingController _paymentTypeController =
TextEditingController(text: 'Payment Type');
final TextEditingController _titleController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
final TextEditingController _transactionDateController =
TextEditingController(text: 'Select Transaction Date');
final TextEditingController _slipValueController = TextEditingController();
final _formkey = GlobalKey<FormState>();
DateTime? picked;
Timestamp? transactionDateStamp;
bool _isLoading = false;
File? imageFile;
String? slipImgUrl;
void _getFromCamera() async {
XFile? pickedFile =
await ImagePicker().pickImage(source: ImageSource.camera);
_cropImage(pickedFile!.path);
Navigator.pop(context);
}
void _getFromGallery() async {
XFile? pickedFile =
await ImagePicker().pickImage(source: ImageSource.gallery);
_cropImage(pickedFile!.path);
Navigator.pop(context);
}
void _cropImage(filePath) async {
CroppedFile? croppedImage = await ImageCropper()
.cropImage(sourcePath: filePath, maxHeight: 1080, maxWidth: 1080);
if (croppedImage != null) {
setState(() {
imageFile = File(croppedImage.path); //<--- Error: the Argument Type String cant be assigned to parameter type List<object>
});
}
}
void _showImageDialog() {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Please Choose an Option'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
onTap: () {
_getFromCamera();
},
child: Row(
children: const [
Padding(
padding: EdgeInsets.all(4.0),
child: Icon(
Icons.camera,
color: Colors.black,
),
),
Text(
'Camera',
style: TextStyle(color: Colors.black),
),
],
),
),
InkWell(
onTap: () {
_getFromGallery();
},
child: Row(
children: const [
Padding(
padding: EdgeInsets.all(4.0),
child: Icon(
Icons.image,
color: Colors.black,
),
),
Text(
'Gallary',
style: TextStyle(color: Colors.black),
),
],
),
),
],
),
);
});
}
//Slip Upload Function ---------------------------------------------------
void _uploadslips() async {
final slipId = const Uuid().v4();
User? user = FirebaseAuth.instance.currentUser;
final _uid = user!.uid;
final isValid = _formkey.currentState!.validate();
if (isValid) {
if (_transactionDateController.text == 'Select Transaction Date' ||
_slipCatagoriesController.text == 'Transaction Type' ||
imageFile == null) {
GlobalMethod.showErrorDialog(
error: 'Please comple all the fields', ctx: context);
return;
}
setState(() {
_isLoading = true;
});
try {
final ref = FirebaseStorage.instance
.ref()
.child('slipImages')
.child(slipId + '.jpg');
await ref.putFile(imageFile!); //<-------Error: The argument File (where is defined in... then a //location path... cant be assigned to a parament type File.
slipImgUrl = await ref.getDownloadURL();
await FirebaseFirestore.instance.collection('Slips').doc(slipId).set({
'slipId': slipId,
'slipImg': imageFile,
'uploadedBy': _uid,
'userName': name,
'userImage': userImage,
'userLocation': location,
'email': user.email,
'transactionType': _slipCatagoriesController.text,
'project': _projectListController.text,
'paymentMethod': _paymentTypeController.text,
'value': _slipValueController.text,
'slipDescription': _descriptionController.text,
'slipDate': _transactionDateController.text,
});
// await Fluttertoast.showToast(
// msg: 'Slip was Successfully uploaded',
// toastLength: Toast.LENGTH_LONG,
// backgroundColor: Colors.black,
// );
_slipCatagoriesController.clear();
_projectListController.clear();
_paymentTypeController.clear();
_slipValueController.clear();
_transactionDateController.clear();
_descriptionController.clear();
setState(() {
_slipCatagoriesController.text = 'Transaction Type';
_projectListController.text = 'Select Project';
_paymentTypeController.text = 'Payment Method';
_slipValueController.text = 'Value R';
_descriptionController.text = 'Description';
_transactionDateController.text = 'Select Transaction Date';
});
} catch (error) {
{
setState(() {
_isLoading = false;
});
GlobalMethod.showErrorDialog(error: error.toString(), ctx: context);
}
} finally {
setState(() {
_isLoading = false;
});
}
} else {
print('Slip not valid');
}
}
//Get Data-------------------------------------------------------------------
void getMyData() async {
final DocumentSnapshot userDoc = await FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.get();
setState(() {
name = userDoc.get('name');
userImage = userDoc.get('userImage');
location = userDoc.get('location');
});
}
#override
void initState() {
super.initState();
getMyData();
}
//Build-------------------------------------------------------------------
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: const Text('Upload Slips (2)'),
centerTitle: true,
backgroundColor: Colors.blue.shade900,
),
bottomNavigationBar: BottomNavigationBarForApp(indexNum: 2),
body: SingleChildScrollView(
child: Column(
children: [
Container(
alignment: Alignment.bottomLeft,
padding: const EdgeInsets.fromLTRB(15, 10, 0, 0),
child: ElevatedButton(
onPressed: () {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => AllSlips()));
},
child: const Text('All Slips'),
),
),
Center(
child: Padding(
padding: const EdgeInsets.all(7.0),
child: Card(
color: Colors.blue.shade900,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
),
const Align(
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.all(7.0),
child: Text(
'Please fill all fields',
style: TextStyle(color: Colors.white),
),
),
),
const SizedBox(
height: 10,
),
const Divider(
thickness: 1,
color: Colors.white,
),
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_textTitles(label: 'Picture of Slip'),
const SizedBox(
height: 10,
),
GestureDetector(
onTap: () {
_showImageDialog();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: Colors.blue,
),
borderRadius:
BorderRadius.circular(100),
),
child: ClipRRect(
borderRadius:
BorderRadius.circular(16),
child: imageFile == null
? const Icon(
Icons.camera_enhance_sharp,
color: Colors.black,
size: 30,
)
: Image.file(
imageFile!, //<--------Error: The argument File (where is defined in... then a //location path... cant be assigned to a parament type File.
fit: BoxFit.fill,
),
),
),
),
),
const SizedBox(
height: 10,
),
_textTitles(label: 'Transaction Type: '),
_textFormField(
valueKey: 'transactionType',
controller: _slipCatagoriesController,
enabled: false,
fct: () {
_transactionTypeCategories(size: size);
},
maxLenth: 50,
),
_textTitles(label: 'Project: '),
_textFormField(
valueKey: 'project',
controller: _projectListController,
enabled: false,
fct: () {
_projectsCategories(size: size);
},
maxLenth: 50,
),
_textTitles(label: 'Payment Method: '),
_textFormField(
valueKey: 'paymentMethod',
controller: _paymentTypeController,
enabled: false,
fct: () {
_paymentType(size: size);
},
maxLenth: 50,
),
_textTitles(label: 'Value'),
_textFormField(
valueKey: 'value',
controller: _slipValueController,
enabled: true,
fct: () {},
maxLenth: 50,
),
_textTitles(label: 'Description'),
_textFormField(
valueKey: 'slipDescription',
controller: _descriptionController,
enabled: true,
fct: () {},
maxLenth: 100,
),
_textTitles(label: 'Transaction Date'),
_textFormField(
valueKey: 'slipDate',
controller: _transactionDateController,
enabled: false,
fct: () {
_pickDateDialog();
},
maxLenth: 100,
),
],
),
),
),
),
Center(
child: Padding(
padding: const EdgeInsets.only(bottom: 30),
child: _isLoading
? const CircularProgressIndicator()
: MaterialButton(
onPressed: () {
_uploadslips();
},
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13),
),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 14, horizontal: 100),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
'Post Now',
style: TextStyle(
color: Colors.blue.shade900),
),
const SizedBox(
width: 9,
),
Icon(
Icons.upload_file,
color: Colors.blue.shade900,
)
],
),
),
),
),
),
],
),
)),
),
),
],
),
),
);
}
}
I have tried to write the function in the onPress event but still no avail.
Thanks!

Related

Flutter - bottomModalSheet can't validate a textfield widget

I have attached a project which is having a bottom modal sheet. Which sheet contains three TextField as name, number and email. So here I have implemented CRUD (Create, read, update and delete) operation and it's fine working. But without validating the TextField it shows in the HomePage. although if I miss to enter name or number still it's passing the data to the homepage card. I have tried many validating options but didn't worked out. If anyone can please help me.
My code:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Map<String, dynamic>> _contacts = [];
bool _isLoading = true;
final bool _validatename = true;
final bool _validatenumber = true;
final bool _validateemail = true;
void _refreshContacts() async {
final data = await Contact.getContacts();
setState(() {
_contacts = data;
_isLoading = false;
});
}
#override
void initState() {
super.initState();
_refreshContacts();
}
final _nameController = TextEditingController();
final _numberController = TextEditingController();
final _emailController = TextEditingController();
final bool _validate = false;
void _showForm(int? id) async {
if (id != null) {
final existingContact = _contacts.firstWhere((element) => element['id'] ==id);
_nameController.text = existingContact['name'];
_numberController.text = existingContact['number'];
_emailController.text = existingContact['email'];
}
showModalBottomSheet(context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => Container(
padding: EdgeInsets.only(top: 15, left: 15, right: 15, bottom: MediaQuery.of(context).viewInsets.bottom + 120),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(
hintText: "Name",
),
),
const SizedBox(
height: 10.0,
),
TextField(
keyboardType: TextInputType.number,
controller: _numberController,
decoration: const InputDecoration(
hintText: "Numbers",
),
),
const SizedBox(
height: 10.0,
),
TextField(
// keyboardType: TextInputType.emailAddress,
controller: _emailController,
decoration: const InputDecoration(
hintText: "Email Address",
),
),
const SizedBox(
height: 20.0,
),
Row(
children: [
ElevatedButton(
onPressed: () async {
if (id == null) {
await _addContact();
}
if (id != null) {
await _updateContact(id);
}
Navigator.of(context).pop();
_nameController.text = '';
_numberController.text = '';
_emailController.text = '';
},
child: Text(id == null ? 'Create New' : 'Update'),
),
const SizedBox(
width: 10.0,
),
ElevatedButton(onPressed: () async {
_nameController.text = '';
_numberController.text = '';
_emailController.text = '';
}, child: const Text("Clear")),
const SizedBox(
width: 10.0,
),
ElevatedButton(onPressed: (){
Navigator.pop(context);
}, child: const Text("Go Back")),
],
),
]),
));
}
Future<void> _addContact() async {
await Contact.createContact(
_nameController.text, _numberController.text, _emailController.text
);
_refreshContacts();
}
Future<void> _updateContact(int id) async {
await Contact.updateContact(id, _nameController.text, _numberController.text, _emailController.text );
_refreshContacts();
}
void _deleteContact(int id) async {
await Contact.deleteContact(id);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Sccessfully Contact Deleted")));
_refreshContacts();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Contact App",),
backgroundColor: Colors.blueAccent,
centerTitle: true,
toolbarHeight: 80,
),
body: _isLoading ? const Center(child: CircularProgressIndicator(),) :
ListView.builder(
itemCount: _contacts.length,
itemBuilder: (context, index) =>
Card(
elevation: 5,
shape: const Border(
right: BorderSide(color: Colors.blue, width: 10.0),
),
color: Colors.orange[200],
margin: const EdgeInsets.all(15.0),
child: Material(
elevation: 20.0,
shadowColor: Colors.blueGrey,
child: ListTile(
title: Text(_contacts[index]['name'], style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(_contacts[index]['number'], style: const TextStyle(color: Colors.grey, fontSize: 18),),
const SizedBox(
height: 5.0,
),
Text(_contacts[index]['email'], style: const TextStyle(fontSize: 17, color: Colors.black),),
],
),
trailing: SizedBox(
width: 100,
child: Row(
children: [
IconButton(onPressed: () => _showForm(_contacts[index]['id']), icon: const Icon(Icons.edit, color: Colors.blueGrey,)),
IconButton(onPressed: () => _deleteContact(_contacts[index]['id']), icon: const Icon(Icons.delete, color: Colors.red,)),
],
),
),
),
),
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add, size: 28,),
onPressed: () => _showForm(null),
),
);
}
}
Above codes are from homepage. I need only the validating part + if anyone can know how to show the each card in another page using page route. Actually this is a contact app. I have tried the new screen to show the full details but couldn't.
You can return when any of the field is empty like
ElevatedButton(
onPressed: () async {
if (_nameController.text.isEmpty ||
_numberController.text.isEmpty ||
_emailController.text.isEmpty) {
return;
}
},
child: Text(id == null ? 'Create New' : 'Update'),
),
But it will be better to use Form widget TextFormFiled with validator . Find more on validation
final _formKey = GlobalKey<FormState>();
showModalBottomSheet(
context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => Container(
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
controller: _nameController,
decoration: const InputDecoration(
hintText: "Name",
),
),
Row(
children: [
ElevatedButton(
onPressed: () async {
final isValided =
_formKey.currentState?.validate();
if (isValided == true) {}
},
child: Text(id == null ? 'Create New' : 'Update'),
),

Flutter default profile picture for signup with u8intlist

The code below is my signup code, it has everything that I need but I got a problem with the default image. I made the connection with firebase but now I need to insert a default picture if the person doesn't chose a profile picture. What is the best way to tackle this?
I use de imagepicker to pick a picture from your own gallery, that is used in a async function called selectimage()
Then the async signup function is the function where the authmethods().signUpUser takes place. In this function it will then say that _image is null and that I can't use the ! operator.
import 'dart:typed_data';
import 'package:event_app/pages/Login_Page.dart';
import 'package:event_app/resources/auth_methods.dart';
import 'package:event_app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import '../utils/colors.dart';
import '../widgets/text_field_input.dart';
import '../widgets/password_field_input.dart';
import 'Verify_Email_Page.dart';
class SignupPage extends StatefulWidget {
const SignupPage({Key? key}) : super(key: key);
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _usernameController = TextEditingController();
bool _isLoading = false;
Uint8List? _image;
#override
void dispose() {
super.dispose();
_emailController.dispose();
_passwordController.dispose();
_usernameController.dispose();
}
void selectImage() async {
Uint8List im = await pickImage(ImageSource.gallery);
setState(() {
_image = im;
});
}
void signUpUser() async {
setState(() {
_isLoading = true;
});
String res = await AuthMethods().signUpUser(
email: _emailController.text,
password: _passwordController.text,
username: _usernameController.text,
file: _image!);
if (res == "Success") {
setState(() {
_isLoading = false;
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const VerifyEmailPage()));
} else {
setState(() {
_isLoading = false;
});
showSnackBar(res, context);
}
}
void navigateToLogin() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const LoginPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 32),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Container(),
flex: 2,
),
SvgPicture.asset(
'assets/ic_instagram.svg',
color: textColor,
height: 64,
),
const SizedBox(
height: 64,
),
Stack(
children: [
_image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(_image!),
backgroundColor: Colors.grey,
)
: const CircleAvatar(
radius: 64,
backgroundImage: NetworkImage(
'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png'),
backgroundColor: Colors.grey,
),
Positioned(
bottom: -10,
left: 80,
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo)))
],
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your username',
textInputType: TextInputType.text,
textEditingController: _usernameController,
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your email',
textInputType: TextInputType.emailAddress,
textEditingController: _emailController,
),
const SizedBox(
height: 24,
),
PasswordFieldInput(
hintText: 'Enter your password',
textInputType: TextInputType.text,
textEditingController: _passwordController,
),
const SizedBox(
height: 24,
),
InkWell(
child: Container(
child: !_isLoading
? const Text('Sign up')
: const Center(
child: CircularProgressIndicator(
color: textColor,
),
),
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
color: accentColor,
),
),
onTap: signUpUser,
),
SizedBox(
height: 12,
),
Flexible(
child: Container(),
flex: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: const Text("Already have an account?"),
padding: const EdgeInsets.symmetric(vertical: 8),
),
GestureDetector(
onTap: navigateToLogin,
child: Container(
child: const Text(
"Login.",
style: TextStyle(fontWeight: FontWeight.bold),
),
padding: const EdgeInsets.symmetric(vertical: 8),
),
)
],
),
],
),
)),
);
}
}
What if you change the selectImage function from async to sync function to prevent api call before _image is set.
void selectImage(){
pickImage(ImageSource.gallery).then(
(im){
setState(() {
_image = im;
});
});
}

Why does my code give an error of a Null Check Operator used on a null value

Here is the code
I wanted to register a user and I used a FormKey and I got the error Null
check operator use don a null value
here is what the run terminal shows
E/flutter (30851): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Null check operator used on a null value
E/flutter (30851): #0 _RegisterScreenState.signUp (package:em_home/screens/signing/register_screen.dart:58:29)
class RegisterScreen extends StatefulWidget {
const RegisterScreen({Key? key}) : super(key: key);
#override
_RegisterScreenState createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
showSnackBar(String content, BuildContext context) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(content)));
}
bool _isLoading = false;
final formKey = GlobalKey<FormState>();
String email = "";
String password = "";
String fullName = "";
String dob = "";
String gender = "";
AuthMethods authMethods = AuthMethods();
Uint8List? image;
pickImage(ImageSource source) async {
final ImagePicker imagePicker = ImagePicker();
XFile? _file = await imagePicker.pickImage(source: source);
if (_file != null) {
return await _file.readAsBytes();
}
print("No Image selected");
}
void selectImage() async {
Uint8List im = await pickImage(ImageSource.gallery);
setState(() {
image = im;
});
}
signUp() async {
if (formKey.currentState!.validate()) {
setState(() {
_isLoading = true;
});
await authMethods.registerUser(email: email, password: password, name: fullName, gender: gender, dateOfBirth: dob,)
.then((value) async {
if (value == true) {
await HelperFunctions.saveUserLoggedInStatus(true);
await HelperFunctions.saveUserEmailSF(email);
await HelperFunctions.saveUserNameSF(fullName);
Navigator.pushReplacement(context, SlideLeftRoute(widget: const LoginScreen()));
} else {
showSnackBar(value, context);
setState(() {
_isLoading = false;
});
}
});
}
return null;
}
void navigatetoSignIn() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const LoginScreen()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor,
body: SingleChildScrollView(
child: Container(
color: backgroundColor,
padding: const EdgeInsets.symmetric(horizontal: 15),
width: double.infinity,
child: Column(
children: [
const SizedBox(
height: 30,
),
Container(
alignment: Alignment.topLeft,
child: IconButton(
onPressed: () {
Navigator.pushReplacement(
context, SlideLeftRoute(widget: const LoginScreen()));
},
icon: const Icon(
Icons.arrow_back,
size: 40,
),
),
),
const SizedBox(
height: 20,
),
Image.asset(
'assets/logos.png',
),
const Text(
"Create your account",
style: TextStyle(color: textColor, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 30,
),
Stack(
children: [
// to check if Image is not equal to null
image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(image!),
)
: const CircleAvatar(
radius: 64,
backgroundImage: AssetImage(
"assets/default_profile.jpg",
),
),
Positioned(
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo),
),
left: 80,
bottom: -10,
)
],
),
const SizedBox(
height: 30,
),
TextFormField(
decoration: textInputDecoration.copyWith(
labelText: "Email",
prefixIcon: Icon(
Icons.email,
)),
onChanged: (val) {
setState(() {
email = val;
});
},
// check tha validation
validator: (val) {
return RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(val!)
? null
: "Please enter a valid email";
},
),
const SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
decoration: textInputDecoration.copyWith(
labelText: "Password",
prefixIcon: Icon(
Icons.lock,
color: backgroundColor,
)),
validator: (val) {
if (val!.length < 6) {
return "Password must be at least 6 characters";
} else {
return null;
}
},
onChanged: (val) {
setState(() {
password = val;
});
},
),
const SizedBox(
height: 20,
),
TextFormField(
decoration: textInputDecoration.copyWith(
labelText: "Full Name",
prefixIcon: Icon(
Icons.person,
)),
onChanged: (val) {
setState(() {
fullName = val;
});
},
validator: (val) {
if (val!.isNotEmpty) {
return null;
} else {
return "Name cannot be empty";
}
},
),
const SizedBox(
height: 20,
),
TextFormField(
decoration: textInputDecoration.copyWith(
labelText: "Date Of Birth DD/MM/YYYY",
prefixIcon: Icon(
Icons.lock,
)),
validator: (val) {},
onChanged: (val) {
setState(() {
dob = val;
});
},
),
const SizedBox(
height: 20,
),
TextFormField(
decoration: textInputDecoration.copyWith(
labelText: "Gender",
prefixIcon: Icon(
Icons.lock,
)),
validator: (val) {},
onChanged: (val) {
setState(() {
gender = val;
});
},
),
const SizedBox(
height: 20,
),
InkWell(
onTap: signUp,
child: Container(
width: double.infinity,
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
color: buttonColor,
),
child: _isLoading
? const Center(
child: CircularProgressIndicator(
color: iconButtonColor,
),
)
: const Text(
"Sign up",
style: TextStyle(
color: buttonTextColor,
fontWeight: FontWeight.bold),
),
),
),
const SizedBox(
height: 50,
),
Container(
color: backgroundColor,
child: const Text("- or sign in using -"),
),
const SizedBox(
height: 25,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
Navigator.push(context, CustomRoute(widget: const Scaffold(body: Center(child: Text("Coming Soon"),))));
},
child: Container(
width: 50,
height: 45,
color: Colors.white,
child: Image.asset('assets/google.png'),
),
),
const SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
Navigator.push(context, CustomRoute(widget: const Scaffold(body: Center(child: Text("Coming Soon"),))));
},
child: Container(
width: 50,
height: 45,
color: Colors.white,
child: Image.asset('assets/facebook.png'),
),
),
],
),
],
),
),
),
);
}
}
please what do I do here is the snippet to the code
Wrap your UI with the FormFields inside a Form widget and pass the GlobalKey to it.
Quick guide from Flutter docs: https://docs.flutter.dev/cookbook/forms/validation

Can't save the right image url on Firestore

Actually I am getting data by user, saving it in a map and adding this item to a list. When user has added all items in the list, it press the floating action button to add this list to an existing list on the firestore.
All data is being saved successfully except the imageUrl. First item in the list has null imageUrl at firestore however the second item is assigned the imageUrl of first Item. And the sequence goes on... I don't know what am I missing! I have subtracted most of code to be specific. I think the problem is being caused by the variable itemImageUrl that is being overridden. Help!
This is the code:
class RetrieveShop extends StatefulWidget {
String nameShop;String docId;
RetrieveShop(this.nameShop,this.docId);
#override
_RetrieveShopState createState() => _RetrieveShopState();
}
class _RetrieveShopState extends State<RetrieveShop> {
var result;
bool isLoading = false;
bool isLoadingNow = false;
var _price = TextEditingController();
var _itemName = TextEditingController();
/* var _id = TextEditingController();
var _category = TextEditingController();*/
var _desc = TextEditingController();
File _image;
File _image2;
String itemImageUrl;
bool _showDg = false;
bool condition = true;
bool isPopular = false;
bool savingAllDataToFirestore = false;
List itemo=[];
Future getImageFromGallery() async {
var image = await ImagePicker()
.getImage(source: ImageSource.gallery, imageQuality: 80);
setState(() {
_image = File(image.path);
print('Image Path $_image');
});
}
Future getImageFromCamera() async {
var image = await ImagePicker().getImage(source: ImageSource.camera);
setState(() {
_image = File(image.path);
print('Image Path $_image');
});
}
Future uploadItemOfShop(BuildContext context) async {
Reference ref = storage.ref().child(
"${this.widget.nameShop}'s ${_itemName.text} Price ${_price.text}" +
DateTime.now().toString());
if (_image.toString() == '') {
Flushbar(
title: "Menu Item Image is empty",
message: "Please Add some Image first",
backgroundColor: Colors.red,
boxShadows: [
BoxShadow(
color: Colors.red[800],
offset: Offset(0.0, 2.0),
blurRadius: 3.0,
)
],
duration: Duration(seconds: 3),
)
..show(context);
} else {
setState(() {
isLoadingNow=true;
});
debugPrint('wah');
UploadTask uploadTask = ref.putFile(_image);
uploadTask.then((res) async {
itemImageUrl = await res.ref.getDownloadURL();
}).then((value){
setState(() {
isLoadingNow=false;
});
debugPrint("Nullifing the Image object");
_image=_image2; //Trying to null the file object after it is used so thinking that might
//the problem is being caused here
});
}
}
Widget listTile(BuildContext context,String doc) {
return !isLoadingNow?SingleChildScrollView(
child: ListTile(
title: Wrap(
// mainAxisAlignment: MainAxisAlignment.start,
direction: Axis.horizontal,
children: [
Text(
"Enter details of Item",
style: TextStyle(fontSize: 22, color: Colors.black87),
),
Stack(
children: [
SizedBox(
width: MediaQuery
.of(context)
.size
.width,
height: MediaQuery
.of(context)
.size
.height / 2.5,
child: (_image != null)
? Image.file(
_image,
fit: BoxFit.cover,
)
: Image.network(
"https://images.unsplash.com/photo-1502164980785-f8aa41d53611?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
fit: BoxFit.fill,
),
),
Container(
alignment: Alignment.topLeft,
color: Colors.white38,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(
Icons.add_a_photo,
size: 30.0,
color: Colors.black,
),
onPressed: () {
getImageFromCamera();
},
),
SizedBox(
width: 10,
),
IconButton(
icon: Icon(
Icons.create_new_folder_rounded,
size: 30.0,
color: Colors.black,
),
onPressed: () {
getImageFromGallery();
},
),
],
),
)
],
),
],
),
subtitle: Column(
children: [
TextField(
controller: _itemName,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Enter Item name',
icon: Icon(Icons.fastfood),
alignLabelWithHint: true,
hintText: "Zinger Burger etc"),
autofocus: true,
),
TextField(
controller: _price,
autofocus: false,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Enter Price',
icon: Icon(Icons.attach_money),
alignLabelWithHint: true,
hintText: "70 etc"),
),
SwitchListTile(
title: condition ? Text("Fresh") : Text("Used"),
value: condition,
onChanged: _onConditionChanged,
),
SwitchListTile(
title: isPopular ? Text("Popular") : Text("Not Popular"),
value: isPopular,
onChanged: _onPopularityChanged,
),
TextField(
autofocus: false,
maxLength: 150,
controller: _desc,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
labelText: 'Enter Description',
icon: Icon(Icons.description),
alignLabelWithHint: true,
hintText:
"This item contains cheez and paneer with delicious mayonees etc.."),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
child: Text(
"Save",
style: TextStyle(color: Colors.white, fontSize: 16),
),
color: Colors.red,
onPressed: () {
if(_image !=null){
int price=int.parse(_price.text);
String itemName=_itemName.text;
String itemDesc=_desc.text;
String categoryO=this.categoryToSave;
String imageUrl=this.itemImageUrl;
uploadItemOfShop(context).then((value){
String idO=getRandomString(3);
var item = {
'itemName': itemName,
'itemPrice': price,
'itemDesc': itemDesc,
'category': categoryO,
'condition': condition,
'imageUrl': imageUrl,
'isPopular': this.isPopular,
'id': idO,
};
setState(() {
itemo.add(item);
});
});
setState(() {
_showDg = false;
});
_price.clear();
_desc.clear();
_itemName.clear();
/* imageUrl='';
itemImageUrl='';*/
}else{
Fluttertoast.showToast(msg: 'Please select some image first');
}
}
),
],
),
],
),
selectedTileColor: Colors.red.shade300,
),
):Padding(
padding: const EdgeInsets.all(40.0),
child: Center(
child:CircularProgressIndicator()
),
);
}
Widget myList(String nameOfButton2, {BuildContext buildContext}) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
StreamBuilder(
stream: FirebaseFirestore.instance.collection('shops').where(
'name', isEqualTo: this.widget.nameShop).snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if(snapshot.hasData){
DocumentSnapshot list=snapshot.data.docs.single;
return isLoadingNow
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: list.data()['menu'].length,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context,int index){
return Card(
shadowColor: Colors.red,
//color: Colors.black,
elevation: 8.0,
//borderOnForeground: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
margin: EdgeInsets.only(
bottom: 10, right: 10),
child: ListTile(
leading: CachedNetworkImage(
fit: BoxFit.cover,
//height: 100,
placeholderFadeInDuration:
Duration(seconds: 2),
fadeOutDuration: Duration(seconds: 2),
imageUrl: list
.data()['menu'][index]['imageUrl'],
progressIndicatorBuilder: (context, url,
downloadProgress) =>
Center(
child:
CircularProgressIndicator(
value: downloadProgress.progress,
color: kPrimaryColor,
)),
errorWidget: (context, url, error) =>
Icon(Icons.error),
),
title:Text('Name: ${list.data()['menu'][index]['itemName']}'),
subtitle: Column(
crossAxisAlignment:CrossAxisAlignment.start,
children:[
Text(
"Price: ${list.data()['menu'][index]['itemPrice']} Rs",
style: TextStyle(
color: Colors.black54,
fontSize: 18),
),
Text(
"Description: ${list.data()['menu'][index]['itemDesc']}",
style: TextStyle(
color: Colors.black87, fontSize: 20),
),
list.data()['menu'][index]['condition']
? Text("Condition: Fresh")
: Text("Condition: Used"),
]
),
),
);
},
);
}
if(snapshot.hasError){
return Text('Please try again');
}
return Center(
child: CircularProgressIndicator(),
);
},
),
]
,
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${this.widget.nameShop}"),
centerTitle: false,
actions: [
IconButton(
icon: Icon(Icons.add_comment),
onPressed: () {
setState(() {
_showDg = !_showDg;
});
})
],
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
_showDg ? listTile(context,this.widget.docId) : Text(""),
myList(this.widget.nameShop),
],
),
),
),
floatingActionButton: FloatingActionButton(
child: Text("Items ${itemo.length.toString()}"),
onPressed: (){
if(itemo.length==0){
Fluttertoast.showToast(msg: 'Please add some items first');
}else{
FirebaseFirestore.instance.collection('shops').doc(this.widget.docId).update({
"menu": FieldValue.arrayUnion(itemo),
});
setState(() {
itemo=[];
});
}
},
),
);
}
}
Was just missing await before the object of uploadtask.

How can I add a new value to my text editcontroller in Text formfield?

I have a database and retrieving my Data from firestore.
class ProductProvider with ChangeNotifier {
UserModel userModel;
List<UserModel> userModelList = [];
Future<void> getUserData() async {
List<UserModel> newList = [];
User currentUser = FirebaseAuth.instance.currentUser;
QuerySnapshot userSnapshot = await FirebaseFirestore.instance
.collection("Manufacturer-Accounts")
.get();
userSnapshot.docs.forEach(
(element) {
if (currentUser.uid == element.data()['Manufacturer_ID']) {
userModel = UserModel(
userFName: element.data()['FirstName'],
userCompany: element.data()['Company'],
userDesignation: element.data()['Designation'],
userEmail: element.data()['Email'],
userPhone: element.data()['PhoneNumber'],
userLastName: element.data()['LastName'],
);
newList.add(userModel);
}
userModelList = newList;
},
);
}
I have retrieved my data as a list and set it to the textformfield like this in a stateful widget as I know the TextEditing Controller should be initiated in stateful widget and should not be as final.
class ProfileScreen extends StatefulWidget {
static String routeName = "/Settings";
#override
_ProfileScreenState createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
var _formKey = GlobalKey<FormState>();
File _pickedImageFile;
PickedFile _pickedImage;
TextEditingController firstName;
TextEditingController lastName;
TextEditingController phoneNumber;
TextEditingController designation;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
User user = FirebaseAuth.instance.currentUser;
void userDetailsUpdate() {
FirebaseFirestore.instance
.collection("Manufacturer-Accounts")
.doc(user.uid)
.update({
'Designation': designation.text,
'FirstName': firstName.text,
'LastName': lastName.text,
//'Email': user.email,
'Phone': phoneNumber.text,
//'UserImage': imageUrl == null ? "" : imageUrl,
});
}
Future<void> getImage({ImageSource source}) async {
_pickedImage = await ImagePicker().getImage(source: source);
if (_pickedImage != null) {
_pickedImageFile = File(_pickedImage.path);
}
}
String imageUrl;
void _uploadImage({File image}) async {
StorageReference storageReference = FirebaseStorage.instance
.ref()
.child('UserImage')
.child("UserImage/${user.uid}");
StorageUploadTask uploadTask = storageReference.putFile(image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
imageUrl = await taskSnapshot.ref.getDownloadURL();
}
Future<void> myDiscardChanges() {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: [
Text("Discard changes?"),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlatButton(
padding: EdgeInsets.all(12),
color: Colors.amber[400],
hoverColor: Colors.blueGrey[300],
child: Text("Yes"),
onPressed: () {
setState(() {
editProfile = false;
});
Navigator.of(context).pop();
},
),
FlatButton(
padding: EdgeInsets.all(12),
color: Colors.amber[400],
hoverColor: Colors.blueGrey[300],
child: Text("No"),
onPressed: () {
setState(() {
editProfile = true;
});
Navigator.of(context).pop();
},
),
],
)
],
),
),
);
},
);
}
Future<void> myDialogBox() {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: [
ListTile(
leading: Icon(Icons.camera_alt),
title: Text("Camera"),
onTap: () {
getImage(source: ImageSource.camera);
Navigator.of(context).pop();
},
),
ListTile(
leading: Icon(Icons.photo_library),
title: Text("Gallery"),
onTap: () {
getImage(source: ImageSource.gallery);
Navigator.of(context).pop();
},
)
],
),
),
);
});
}
bool editProfile = false;
ProductProvider productProvider;
Widget newBuildTrue() {
List<UserModel> userModel = productProvider.getUserModelList;
return Column(
children: userModel.map((e) {
//userImage = e.userImage;
return Container(
child: Column(
children: [
buildContainerTrue(
startText: "First Name",
endText: e.userFName,
),
buildContainerTrue(
startText: "Last Name",
endText: e.userLastName,
),
buildContainerTrue(
startText: "E-mail",
endText: e.userEmail,
),
buildContainerTrue(
startText: "Designation",
endText: e.userDesignation,
),
buildContainerTrue(
startText: "Company",
endText: e.userCompany,
),
buildContainerTrue(
startText: "Telephone No",
endText: (e.userPhone).toString(),
),
],
),
);
}).toList(),
);
}
String userImage;
Widget newBuildFalse() {
List<UserModel> userModel = productProvider.getUserModelList;
return Column(
children: userModel.map((e) {
//userImage = e.userImage;
firstName = TextEditingController(text: e.userFName);
lastName = TextEditingController(text: e.userLastName);
phoneNumber = TextEditingController(text: e.userPhone);
designation = TextEditingController(text: e.userDesignation);
return Container(
child: Column(
children: [
// buildTextFormField(editText: "FirstName"),
MyTextFormField(
name: "FirstName",
controller: firstName,
),
MyTextFormField(
name: "LastName",
controller: lastName,
),
buildContainerTrue(
startText: "E-mail",
endText: e.userEmail,
),
MyTextFormField(
name: "Designation",
controller: designation,
),
buildContainerTrue(
startText: "Company",
endText: e.userCompany,
),
MyTextFormField(
name: "Telephone No",
controller: phoneNumber,
),
],
),
);
}).toList(),
);
}
#override
void initState() {
super.initState();
}
#override
void dispose() {
//firstName.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
productProvider = Provider.of<ProductProvider>(context);
productProvider.getUserData();
ScreenUtil.init(context, height: 896, width: 414, allowFontScaling: true);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: editProfile == false
? IconButton(
icon: Icon(Icons.menu),
color: kPrimaryColor,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MenuFrame(),
),
);
},
)
: Container(),
elevation: 1,
actions: [
editProfile == false
? IconButton(
icon: Icon(Icons.edit),
color: kPrimaryColor,
onPressed: () {
setState(() {
editProfile = true;
});
},
)
: IconButton(
icon: Icon(Icons.close),
color: kPrimaryColor,
onPressed: () {
myDiscardChanges();
},
),
],
),
body: Form(
key: _formKey,
child: Container(
height: double.infinity,
width: double.infinity,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: kSpacingUnit.w * 10,
width: kSpacingUnit.w * 10,
margin: EdgeInsets.only(top: kSpacingUnit.w * 3),
child: Stack(
children: <Widget>[
CircleAvatar(
radius: kSpacingUnit.w * 8,
backgroundImage: _pickedImageFile == null
? AssetImage('assets/images/12.jpg')
: FileImage(_pickedImageFile),
),
editProfile == true
? Align(
alignment: Alignment.bottomRight,
child: Container(
height: kSpacingUnit.w * 2.5,
width: kSpacingUnit.w * 2.5,
decoration: BoxDecoration(
color: kAccentColor,
shape: BoxShape.circle,
),
child: Center(
heightFactor: kSpacingUnit.w * 1.5,
widthFactor: kSpacingUnit.w * 1.5,
child: GestureDetector(
onTap: () {
myDialogBox();
},
child: Icon(
LineAwesomeIcons.pen,
color: kDarkPrimaryColor,
size: ScreenUtil()
.setSp(kSpacingUnit.w * 1.5),
),
),
),
),
)
: Container(),
],
)),
SizedBox(height: kSpacingUnit.w * 1.5),
editProfile == false ? newBuildTrue() : newBuildFalse(),
editProfile == true
? FlatButton(
color: Colors.amber,
height: 50,
minWidth: 400,
child: Text("Save"),
onPressed: () {
userDetailsUpdate();
//_uploadImage(image: _pickedImageFile);
setState(() {
editProfile = false;
});
},
)
: Container(),
],
),
),
),
),
);
}
Widget buildContainerTrue({String startText, String endText}) {
return Container(
height: kSpacingUnit.w * 5.5,
margin: EdgeInsets.symmetric(
horizontal: kSpacingUnit.w * 2,
).copyWith(
bottom: kSpacingUnit.w * 2,
),
padding: EdgeInsets.symmetric(
horizontal: kSpacingUnit.w * 1.5,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(kSpacingUnit.w * 3),
color: kDarkSecondaryColor,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
width: 100,
height: kSpacingUnit.w * 5.5,
decoration: BoxDecoration(
// color: Colors.green,
border: Border(
right: BorderSide(color: Colors.white, width: 1),
),
),
child: Text(
startText,
style: TextStyle(color: Colors.white, fontSize: 12),
textAlign: TextAlign.left,
),
),
SizedBox(width: kSpacingUnit.w * 1.5),
Text(
endText,
style: kTitleTextStyle.copyWith(
fontWeight: FontWeight.w500,
color: Colors.amber,
fontSize: 12,
),
),
],
),
);
}
But still following the procedures I am facing an issue like when I enter my new value to the controller it still shows a new value when my keyboard exit. Tried lot of ways and still having the same issue.
Making changes to my functions it actually worked.
Widget newBuildTrue() {
List<UserModel> userModel = productProvider.getUserModelList;
return Column(
children: userModel.map((e) {
firstName = TextEditingController(text: e.userFName);
lastName = TextEditingController(text: e.userLastName);
phoneNumber = TextEditingController(text: e.userPhone);
designation = TextEditingController(text: e.userDesignation);
//userImage = e.userImage;
return Container(
child: Column(
children: [
buildContainerTrue(
startText: "First Name",
endText: e.userFName,
),
buildContainerTrue(
startText: "Last Name",
endText: e.userLastName,
),
buildContainerTrue(
startText: "E-mail",
endText: e.userEmail,
),
buildContainerTrue(
startText: "Designation",
endText: e.userDesignation,
),
buildContainerTrue(
startText: "Company",
endText: e.userCompany,
),
buildContainerTrue(
startText: "Telephone No",
endText: (e.userPhone).toString(),
),
],
),
);
}).toList(),
);
}
String userImage;
Widget newBuildFalse() {
List<UserModel> userModel = productProvider.getUserModelList;
return Column(
children: userModel.map((e) {
//userImage = e.userImage;
return Container(
child: Column(
children: [
// buildTextFormField(editText: "FirstName"),
MyTextFormField(
name: "FirstName",
controller: firstName,
),
buildTextFormField(
editText: "LastName",
textEditingController: lastName,
),
buildContainerTrue(
startText: "E-mail",
endText: e.userEmail,
),
MyTextFormField(
name: "Designation",
controller: designation,
),
buildContainerTrue(
startText: "Company",
endText: e.userCompany,
),
MyTextFormField(
name: "Telephone No",
controller: phoneNumber,
),
],
),
);
}).toList(),
);
}