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

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(),
);
}

Related

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]

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!

Product list is not Showing in this flutter screen

My product has been added to Firebase, but there is a problem with the dashboard's list not appearing. No errors are displayed on the console or the screen.I'm not sure where the problem is appearing in the code or firebase. I'm basically developing an e-commerce app that users should use to sell their goods.
class _SellerDashBoardState extends State<SellerDashBoard> {
MaterialColor active = Colors.red;
MaterialColor notActive = Colors.grey;
List<SellerProductItem> products = [
const SellerProductItem(),
];
#override
Widget build(BuildContext context) {
print(parentIdGlobal);
print(FirebaseAuth.instance.currentUser!.uid);
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text(
'Seller Dashboard',
style: TextStyle(
fontSize: ResponsiveWidget.isSmallScreen(context) ? 17.0 : 25.0),
),
actions: [
IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 27.0,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => AddProductForm(),
),
);
},
),
IconButton(
icon: WebsafeSvg.asset(
'assets/images/sold-out.svg',
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => SoldItemScreens(),
),
);
},
),
],
),
body: Column(
children: <Widget>[
const SizedBox(
height: 10.0,
),
Container(
color: const Color(0xffF7F7F7),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("items")
.where('seller', isEqualTo: parentIdGlobal)
.where('isSold', isEqualTo: true)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final List<QueryDocumentSnapshot<Map<String, dynamic>>>
docSnapList = snapshot.data?.docs ?? [];
if (docSnapList.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: WebsafeSvg.asset(
'assets/images/empty_dashboard.svg',
fit: BoxFit.cover,
height: MediaQuery.of(context).size.height / 5,
),
),
);
}
final List<Map<String, dynamic>> docList = docSnapList
.map((QueryDocumentSnapshot<Map<String, dynamic>>
queryDocumentSnapshot) =>
queryDocumentSnapshot.data())
.toList();
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: docList.length,
itemBuilder: (context, index) {
bool isSold = docList[index]['isSold'] ?? true;
bool isLiked = docList[index]['isLiked'] ?? true;
String itemId = docList[index]['itemId'] ?? '';
String seller = docList[index]['seller'] ?? '';
String sellerName = docList[index]['sellerName'] ?? '';
String title = docList[index]['title'] ?? '';
String desc = docList[index]['desc'] ?? '';
String price = docList[index]['price'] ?? '';
String condition = docList[index]['condition'] ?? '';
String category = docList[index]['category'] ?? '';
String location = docList[index]['location'] ?? '';
String itemImage =
docList[index]['imageDownloadUrl'] ?? '';
return SellerProductItem(
itemId: itemId,
seller: seller,
sellerName: sellerName,
title: title,
desc: desc,
price: price,
itemImage: itemImage,
isLiked: isLiked,
isSold: isSold,
category: category,
condition: condition,
location: location,
);
},
);
},
add product screen
class _AddProductFormState extends State<AddProductForm> {
TextEditingController controllerTitle = TextEditingController();
TextEditingController controllerPrice = TextEditingController();
TextEditingController controllerDescription = TextEditingController();
TextEditingController controllerlocation = TextEditingController();
GlobalKey<FormState> _formKey = GlobalKey();
String selectedCondition = 'New';
String selectedCategory = 'Cosmetic Aids';
bool isReadOnly = true;
File? pickedImage;
bool imgStatus = false;
List<String> conditionList = [
'New',
'Like New',
'Good',
'Fair',
'Poor',
];
List<String> categoryList = [
'Cosmetic Aids',
'Mobility Products',
'Bath Safety Products',
'Others',
];
bool _switchValue = false;
Future<void> addGroceryItemToToDb() async {
final itemId = Uuid().v4();
String? url;
if (pickedImage != null) {
print(parentIdGlobal);
print(FirebaseAuth.instance.currentUser!.uid);
Reference storage = FirebaseStorage.instance
.ref()
.child('users/${FirebaseAuth.instance.currentUser!.uid}/$itemId/item_pic');
UploadTask uploadTask = storage.putFile(pickedImage!);
final temp = await (await uploadTask).ref.getDownloadURL();
url = temp.toString();
}
FirebaseFirestore.instance.collection('items').doc(itemId).set(
{
'itemId': itemId,
'timestamp': DateTime.now(),
'seller': parentIdGlobal,
'sellerName': userNameGlobal,
'title': controllerTitle.text,
'price': controllerPrice.text,
'desc': controllerDescription.text,
'condition': selectedCondition,
'category': selectedCategory,
'location': controllerlocation.text,
'isSold': false,
'imageDownloadUrl': url,
},
);
} // adds grocery item to db
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 1.0,
centerTitle: true,
title: Text(
'Add a Product',
),
),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
_selectImageButton(context),
_writeTitle(),
_writePrice(),
_giveitfree(),
_conditionDropDown(),
_writeDescription(),
_categoryDropDown(),
_writeLocation(),
Align(
alignment: Alignment.bottomCenter,
child: _addProductButton(context)),
],
),
),
),
);
}
_selectImageButton(BuildContext context) {
return GestureDetector(
onTap: () async {
await Permission.photos.request();
var status = await Permission.photos.status;
if (status.isGranted) {
try {
XFile? _pickedImage = await ImagePicker().pickImage(
source: ImageSource.gallery,
maxWidth: 100,
maxHeight: 100,
imageQuality: 100
) ;
if(_pickedImage !=null){
pickedImage = File(_pickedImage.path);
setState(() {
imgStatus = true;
});
} }catch (e) {
print(e.toString());
}
} else if (status.isDenied || status.isRestricted) {
print('Permission Denied');
showDialog(
context: context,
builder: (context) {
if (Platform.isAndroid)
return AlertDialog(
title: Text('Permission Not Granted'),
content:
Text('The permission for photo library is not granted'),
actions: [
ElevatedButton(
onPressed: () => openAppSettings(),
child: Text('Ok'),
),
],
);
return CupertinoAlertDialog(
title: Text('Permission Not Granted'),
content:
Text('The permission for photo library is not granted'),
actions: [
ElevatedButton(
onPressed: () => openAppSettings(),
child: Text('Ok'),
),
],
);
});
} else if (status.isDenied) {
print('Permission Undetermined');
}
},
child: Padding(
padding: EdgeInsets.only(
top: 10.0,
bottom: 10.0,
),
child: Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.transparent,
border: Border.all(
style: BorderStyle.solid,
color: Colors.red,
),
),
child: pickedImage == null
? Icon(
Icons.add,
color: Colors.red,
)
: Image.file(
pickedImage!,
fit: BoxFit.contain,
),
),
),
);
}
ButtonTheme _addProductButton(BuildContext context) {
return ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.1,
child: ElevatedButton(
onPressed: imgStatus
? () async {
if (_formKey.currentState?.validate() == true) {
try {
Navigator.pop(context);
await addGroceryItemToToDb();
} catch (error) {
print(error);
}
}
}
: null,
child: Text(
'Add Product',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
Padding _writeDescription() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerDescription,
maxLines: 5,
inputFormatters: [
new LengthLimitingTextInputFormatter(
1450,
),
],
maxLength: 1450,
decoration: InputDecoration(
alignLabelWithHint: true,
isDense: true,
labelText: 'Description',
helperText: "Describe what you're selling in detail",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
Padding _conditionDropDown() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: conditionDropdownbuttonStyle(),
);
}
Widget conditionDropdownbuttonStyle() {
List<Text> pickerItems = [];
for (String condition in conditionList) {
pickerItems.add(Text(condition));
}
if (Platform.isIOS) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Condition',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
CupertinoPicker(
backgroundColor: Colors.white70,
useMagnifier: true,
itemExtent: 32.0,
diameterRatio: 2,
scrollController: FixedExtentScrollController(initialItem: 0),
magnification: 1.2,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
selectedCondition = conditionList[selectedIndex];
print(selectedCondition);
},
children: pickerItems,
),
],
);
}
List<DropdownMenuItem<String>> dropDownItem = [];
for (String condition in conditionList) {
print(condition);
var newItem = DropdownMenuItem<String>(
child: Text(condition),
value: condition,
);
dropDownItem.add(newItem);
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Condition',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 10.0,
),
Expanded(
child: DropdownButton<String>(
items: dropDownItem,
isExpanded: true,
value: selectedCondition,
hint: Text(
'Condition',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onChanged: (value) {
setState(() {
if (value != null) {
selectedCondition = value;
}
});
},
),
)
],
);
}
Padding _categoryDropDown() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: categoryDropdownbuttonStyle(),
);
}
Widget categoryDropdownbuttonStyle() {
List<Text> pickerItems1 = [];
for (String category in categoryList) {
pickerItems1.add(Text(category));
}
if (Platform.isIOS) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Category',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
CupertinoPicker(
backgroundColor: Colors.white70,
useMagnifier: true,
itemExtent: 32.0,
diameterRatio: 2,
scrollController: FixedExtentScrollController(initialItem: 0),
magnification: 1,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
selectedCategory = categoryList[selectedIndex];
print(selectedCategory);
},
children: pickerItems1,
),
],
);
}
List<DropdownMenuItem<String>> dropDownItem = [];
for (String category in categoryList) {
print(category);
var newItem = DropdownMenuItem<String>(
child: Text(category),
value: category,
);
dropDownItem.add(newItem);
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Category',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 10.0,
),
Expanded(
child: DropdownButton<String>(
items: dropDownItem,
isExpanded: true,
value: selectedCategory,
hint: Text(
'Category',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onChanged: (value) {
setState(() {
if (value != null) {
selectedCategory = value;}
});
},
),
)
],
);
}
Padding _giveitfree() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Give it away for free',
maxLines: 1,
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
switchButtonType(),
],
),
);
}
Widget _writePrice() {
if (_switchValue) {
return Container(
width: 0.0,
height: 0.0,
);
}
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerPrice,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
5,
),
FilteringTextInputFormatter.digitsOnly,
],
decoration: InputDecoration(
prefixIcon: Icon(Icons.attach_money),
isDense: true,
labelText: 'Price',
helperText: 'Set your Price',
hintText: 'Default Price: 0 \u0024',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
Padding _writeTitle() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
validator: (value) {
if (value != null) {
if (value.length < 5) {
return 'The title should be at least 5 characters';
}
return null;
};
return null;},
controller: controllerTitle,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
50,
),
],
decoration: InputDecoration(
prefixIcon: Icon(
Icons.title,
),
isDense: true,
labelText: 'Title*',
labelStyle: TextStyle(
color: Colors.red,
),
helperText: 'Describe your Product in few words',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
8.0,
),
),
),
),
);
}
Padding _writeLocation() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerlocation,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
50,
),
],
decoration: InputDecoration(
prefixIcon: Icon(
Icons.location_on,
),
suffixIcon: IconButton(
icon: Icon(Icons.near_me),
onPressed: getLocation,
),
isDense: true,
labelText: 'Location',
helperText: 'Eg: Austin,Texas',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
getLocation() async {
try {
await Permission.location.request();
var status = await Permission.location.status;
if (status.isGranted) {
print('Permission Granted');
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
print(position);
double latitude = position.latitude;
double longitude = position.longitude;
print('latitude: $latitude \n longitude: $longitude');
List<Placemark> placemark = await placemarkFromCoordinates(
latitude,
longitude,
);
setState(() {
print(placemark[0]);
controllerlocation.text =
('${placemark[0].locality},${placemark[0].administrativeArea},${placemark[0].country}')
.toString();
});
} else if (status.isDenied || status.isRestricted) {
print('Permission Denied');
Widget switchButtonType() {
if (Platform.isAndroid) {
return Switch(
value: _switchValue,
onChanged: (value) {
setState(
() {
_switchValue = value;
isReadOnly = _switchValue;
controllerPrice.text = '0';
print(_switchValue);
},
);
},
);
}
return CupertinoSwitch(
value: _switchValue,
onChanged: (value) {
setState(
() {
_switchValue = value;
isReadOnly = _switchValue;
controllerPrice.text = '0';
print(_switchValue);
},
You are filtering items that have isSold set to true but when adding you are adding with isSold set to false. Maybe you should change your filter to .where('isSold', isEqualTo: false)?

Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast flutter

I'm trying to make a simple messaging application while using firebase and flutter, everything was working fine until I came to the message screen, but on this screen, I get the error that I will specify below. Do you know the solution for this?
Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast
I could not understand where I got the error, when I click on any user on the page where I listed the users, it gives this error directly.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_6.dart';
import 'package:ourchat/pallete.dart';
import 'package:ourchat/shared/utils.dart';
class ChatDetailPage extends StatefulWidget {
final String user;
const ChatDetailPage({
Key? key,
required this.user,
}) : super(key: key);
#override
_ChatDetailPageState createState() => _ChatDetailPageState();
}
class _ChatDetailPageState extends State<ChatDetailPage> {
TextEditingController messageController = TextEditingController();
final currentUserId = FirebaseAuth.instance.currentUser?.uid;
CollectionReference chats = FirebaseFirestore.instance.collection('chats');
var chatDocId;
var userData = {};
bool isLoading = false;
#override
void initState() {
super.initState();
getData();
checkUser();
}
void checkUser() async {
await chats
.where('users', isEqualTo: {userData['uid']: null, currentUserId: null})
.limit(1)
.get()
.then(
(QuerySnapshot querySnapshot) async {
if (querySnapshot.docs.isNotEmpty) {
setState(() {
chatDocId = querySnapshot.docs.single.id;
});
print(chatDocId);
} else {
await chats.add({
'users': {currentUserId: null, widget.user: null},
'names': {
currentUserId: FirebaseAuth.instance.currentUser?.displayName,
userData['uid']: userData['username']
}
}).then((value) => {chatDocId = value});
}
},
)
.catchError((error) {});
}
getData() async {
setState(() {
isLoading = true;
});
try {
var userSnap = await FirebaseFirestore.instance
.collection('users')
.doc(widget.user)
.get();
userData = userSnap.data()!;
print(userData);
setState(() {});
} catch (e) {
showSnackBar(
context,
e.toString(),
);
}
setState(() {
isLoading = false;
});
}
void sendMessage(String msg) {
if (msg == '') return;
chats.doc(chatDocId).collection('messages').add({
'createdOn': FieldValue.serverTimestamp(),
'uid': currentUserId,
'friendName': userData['username'],
'msg': msg
}).then((value) {
messageController.text = '';
});
}
bool isSender(String friend) {
return friend == currentUserId;
}
Alignment getAlignment(friend) {
if (friend == currentUserId) {
return Alignment.topRight;
}
return Alignment.topLeft;
}
#override
Widget build(BuildContext context) {
return isLoading
? const Center(
child: CircularProgressIndicator(),
)
: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(chatDocId)
.collection('messages')
.orderBy('createdOn', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Bir şeyler yanlış gitti..."),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
color: kBlue,
),
);
}
if (snapshot.hasData) {
var data;
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
flexibleSpace: SafeArea(
child: Container(
padding: EdgeInsets.only(right: 16),
child: Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: ImageIcon(
AssetImage("assets/icons/backicon.png"),
color: Colors.white,
),
),
SizedBox(
width: 2,
),
CircleAvatar(
backgroundImage:
NetworkImage(userData['photoUrl'].toString()),
maxRadius: 20,
),
SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
userData['username'].toString(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white),
),
SizedBox(
height: 6,
),
Text(
userData['bio'].toString(),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 13,
),
),
],
),
),
Icon(
Icons.settings,
color: Colors.white,
),
],
),
),
),
),
body: Stack(
children: <Widget>[
ListView(
reverse: true,
children: snapshot.data!.docs.map(
(DocumentSnapshot documentSnapshot) {
data = documentSnapshot.data()!;
print(documentSnapshot.toString());
print(data['msg']);
return Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: ChatBubble(
clipper: ChatBubbleClipper6(
nipSize: 0,
radius: 0,
type: isSender(data['uid'].toString())
? BubbleType.sendBubble
: BubbleType.receiverBubble,
),
alignment: getAlignment(data['uid'].toString()),
margin: EdgeInsets.only(top: 20),
backGroundColor:
isSender(data['uid'].toString())
? Color(0xFF08C187)
: Color(0xffE7E7ED),
child: Container(
constraints: BoxConstraints(
maxWidth:
MediaQuery.of(context).size.width * 0.7,
),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(data['msg'],
style: TextStyle(
color: isSender(data['uid']
.toString())
? Colors.white
: Colors.black),
maxLines: 100,
overflow: TextOverflow.ellipsis)
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Text(
data['createdOn'] == null
? DateTime.now().toString()
: data['createdOn']
.toDate()
.toString(),
style: TextStyle(
fontSize: 10,
color: isSender(
data['uid'].toString())
? Colors.white
: Colors.black),
)
],
)
],
),
),
),
);
},
).toList(),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
padding:
EdgeInsets.only(left: 10, bottom: 10, top: 10),
height: 60,
width: double.infinity,
color: Colors.black,
child: Row(
children: <Widget>[
GestureDetector(
onTap: () {},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: kBlue,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 26,
),
),
),
SizedBox(
width: 15,
),
Expanded(
child: TextField(
controller: messageController,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: "Lütfen mesaj yazınız.",
labelStyle:
TextStyle(color: Colors.white),
hintStyle: TextStyle(color: Colors.white),
border: InputBorder.none),
),
),
SizedBox(
width: 15,
),
GestureDetector(
onTap: () {
sendMessage(messageController.text);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: kBlue,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.send,
color: Colors.white,
size: 20,
),
),
),
],
),
),
),
],
),
);
}
return null!;
},
);
}
}

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.

Flutter table_calendar load today

Im using table_calendar package in my project, but ive faced two problems so far :
The calendar doesnt load todays events below the calendar, i would love to hear some ideas how to get this one done.
Even if i put (code below) in tables parameters, it doesnt allow to switch calendar modes.
code for swiching calendar modes for 2nd bullet point of my problems:
availableCalendarFormats: const {
CalendarFormat.month: '',
CalendarFormat.week: '',
},
Just in case, here is the whole code for page which has problems :
class Lecture_graph extends StatefulWidget {
Lecture_graph({Key key}) : super(key: key);
#override
State<Lecture_graph> createState() => myLectureGraph();
}
class myLectureGraph extends State<Lecture_graph>
with TickerProviderStateMixin {
List _selectedEvents;
DateTime _selectedDate = DateTime.now();
Map<DateTime, List<Lecture>> _events;
CalendarController _calendarController;
AnimationController _animationController;
List<Lecture> _lectures;
String coursecode = "";
bool isJoin, isBreaks = false;
bool isLoading = true;
final Map<DateTime, List> _holidays = {
// DateTime(2021, 1, 1): ['New Year\'s Day'],
// DateTime(2021, 2, 14): ['Valentine\'s Day'],
// DateTime(2021, 3, 8): ['Woman\'s Day'],
};
Future<Map<DateTime, List>> getLectures(DateTime _selectedDate) async {
print("getLectures started.");
setState(() {
isLoading = true;
});
Map<DateTime, List<Lecture>> mapFetch = {};
//get saved course
if (coursecode == "" || coursecode == null) {
coursecode = await _checkSavedCourse();
//debug
print('courscode recieved from sharedprefs');
}
//build request URL
var requestURL =
'https://lekcijas.va.lv/lekcijas_android/getMonthLectures.php?date=' +
DateFormat('yyyy-MM').format(_selectedDate) +
(isBreaks ? "&breaks" : "") +
(isJoin ? "&join" : "") +
"&program=" +
coursecode +
"&lang=" +
AppLocalizations.of(context).translate('request_language');
print("Lecture request url : $requestURL");
//wait for response
var response = await http.get(Uri.parse(requestURL));
var data = json.decode(response.body)["result"];
//clear array after each request
if (_lectures != null) _lectures.clear();
try {
//create lectures from json response
_lectures = List<Lecture>.from(data.map((x) => Lecture.fromJson(x)));
} on Exception catch (_) {
print("Error occured getting lectures");
}
_lectures.forEach((element) {
if (mapFetch[element.lecture_date] != null) {
mapFetch[element.lecture_date] += [element];
} else {
mapFetch[element.lecture_date] = [element];
}
});
setState(() {
isLoading = false;
});
print("getLectures finished.");
return mapFetch;
}
Future<void> _saveVales(String key, bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
print("Sharedpref $key is set to $value now");
prefs.setBool(key, value);
}
Future<void> _checkSavedParameters() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
isBreaks = prefs.getBool('lectures_breaks') == null
? false
: prefs.getBool('lectures_breaks');
isJoin = prefs.getBool('lectures_join') == null
? false
: prefs.getBool('lectures_join');
}
Future<String> _checkSavedCourse() async {
//check saved parameters for lecture requests too
await _checkSavedParameters();
SharedPreferences prefs = await SharedPreferences.getInstance();
String _coursecode = prefs.getString('savedCourse');
if (_coursecode == "" || _coursecode == null) {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CourseSelectionPage()),
);
return null;
} else {
return _coursecode;
}
}
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
setState(() {
_selectedEvents = events;
});
}
#override
void initState() {
super.initState();
//enable portrait only mode
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
_selectedEvents = [];
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
_animationController.forward();
WidgetsBinding.instance.addPostFrameCallback((_) {
getLectures(_selectedDate).then((val) => setState(() {
_events = val;
}));
});
}
#override
void dispose() {
_calendarController.dispose();
//unlock orientation mode
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(coursecode +
" | " +
AppLocalizations.of(context).translate('lectures_title')),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text(
AppLocalizations.of(context).translate('settings')),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
CupertinoSwitch(
value: isJoin,
onChanged: (bool value) {
_saveVales('lectures_join', value);
isJoin = value;
WidgetsBinding.instance
.addPostFrameCallback((_) {
getLectures(_selectedDate)
.then((val) => setState(() {
_events = val;
}));
});
},
),
Text(AppLocalizations.of(context)
.translate('join_lectures'))
],
),
SizedBox(height: 10),
Row(
children: [
CupertinoSwitch(
value: isBreaks,
onChanged: (bool value) {
_saveVales('lectures_breaks', value);
isBreaks = value;
WidgetsBinding.instance
.addPostFrameCallback((_) {
getLectures(_selectedDate)
.then((val) => setState(() {
_events = val;
}));
});
},
),
Text(AppLocalizations.of(context)
.translate('show_breaks'))
],
),
SizedBox(height: 10),
SizedBox(
width: double.infinity,
child: OutlinedButton(
onPressed: () {
//close popup
Navigator.pop(context);
//close page
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CourseSelectionPage()),
);
},
child: Text(
AppLocalizations.of(context)
.translate('select_course'),
style: TextStyle(color: Colors.lime),
)),
)
],
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)
.translate('close')),
),
],
);
},
);
},
);
},
)
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
isLoading
? Expanded(child: Center(child: CircularProgressIndicator()))
: _buildTableCalendarWithBuilders(),
const SizedBox(height: 2.0),
Expanded(child: _buildEventList()),
],
),
),
);
}
Widget _buildTableCalendarWithBuilders() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
color: Colors.white,
margin: const EdgeInsets.all(8.0),
clipBehavior: Clip.antiAlias,
child: TableCalendar(
locale:
AppLocalizations.of(context).translate('request_language') ==
'lv'
? "lv_LV"
: "en_US",
initialSelectedDay: _selectedDate,
calendarController: _calendarController,
events: _events,
holidays: _holidays,
initialCalendarFormat: CalendarFormat.month,
formatAnimation: FormatAnimation.scale,
startingDayOfWeek: StartingDayOfWeek.monday,
availableGestures: AvailableGestures.all,
availableCalendarFormats: const {
CalendarFormat.month: '',
CalendarFormat.week: '',
},
calendarStyle: CalendarStyle(
outsideDaysVisible: false,
weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
),
daysOfWeekStyle: DaysOfWeekStyle(
weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonVisible: false,
),
builders: CalendarBuilders(
selectedDayBuilder: (context, date, _) {
return FadeTransition(
opacity:
Tween(begin: 0.0, end: 1.0).animate(_animationController),
child: Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.deepOrange[300],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
),
);
},
todayDayBuilder: (context, date, _) {
return Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.amber[400],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
);
},
markersBuilder: (context, date, events, holidays) {
final children = <Widget>[];
if (events.isNotEmpty) {
children.add(
Positioned(
right: 1,
bottom: 1,
child: _buildEventsMarker(date, events),
),
);
}
if (holidays.isNotEmpty) {
children.add(
Positioned(
right: -2,
top: -2,
child: _buildHolidaysMarker(),
),
);
}
return children;
},
),
onDaySelected: (date, events, holidays) {
_onDaySelected(date, events);
_animationController.forward(from: 0.0);
},
onVisibleDaysChanged: _onVisibleDaysChanged,
),
),
],
);
}
void _onVisibleDaysChanged(
DateTime first, DateTime last, CalendarFormat format) {
_selectedDate = first;
WidgetsBinding.instance.addPostFrameCallback((_) {
getLectures(_selectedDate).then((val) => setState(() {
_events = val;
}));
});
print('CALLBACK: _onVisibleDaysChanged');
}
Widget _buildEventsMarker(DateTime date, List events) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _calendarController.isSelected(date)
? Colors.brown[500]
: _calendarController.isToday(date)
? Colors.brown[300]
: Colors.green[400],
),
width: 18.0,
height: 18.0,
child: Center(
child: Text(
'${events.length}',
style: TextStyle().copyWith(
color: Colors.white, fontSize: 12.0, fontWeight: FontWeight.w900),
),
),
);
}
Widget _buildHolidaysMarker() {
return Icon(
Icons.add_box,
size: 20.0,
color: Colors.blueGrey[800],
);
}
Widget _buildEventList() {
return ListView(
children: _selectedEvents.reversed
.map((lecture) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.1),
// borderRadius: BorderRadius.circular(2.0),
color: hexToColor(lecture.color),
),
margin:
const EdgeInsets.symmetric(horizontal: 6.0, vertical: 1.5),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
lecture.start + " - " + lecture.end,
style: new TextStyle(
fontSize: 12.0,
color: Colors.black,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(lecture.lecture,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
onTap: () => displayDialog(lecture, context),
),
))
.toList(),
);
}
void displayDialog(Lecture selectedLecture, BuildContext ctx) {
//if selected lecture is a break
if (!selectedLecture.lecturer.isEmpty &&
!selectedLecture.classroom.isEmpty &&
!selectedLecture.programs.isEmpty) {
showDialog(
barrierDismissible: true,
context: ctx,
builder: (BuildContext context) => new AlertDialog(
title: new Text(AppLocalizations.of(context).translate('info_title')),
content: new Wrap(
runSpacing: 5,
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_time') +
selectedLecture.start +
" - " +
selectedLecture.end),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_lecturer') +
selectedLecture.lecturer),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_classroom') +
selectedLecture.classroom),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_lecture') +
selectedLecture.lecture),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_date') +
DateFormat('yyyy-MM-dd')
.format(selectedLecture.lecture_date)
.toString()),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_programs') +
selectedLecture.programs),
),
],
),
actions: [
new TextButton(
child: Text(AppLocalizations.of(context).translate('close')),
onPressed: () => Navigator.pop(context, true),
),
],
),
);
}
}
}
In case someone wants to see JSON request results, here is the link for that.
So i got this fixed, adding this to TableCalendar() parameters:
(i called selectedEvents variable update once calendar finished building (because im showing CircularProgressIndicator instead of it while i recieve data from http request) )
onCalendarCreated: (d1, d2, cf){WidgetsBinding.instance
.addPostFrameCallback((_) => _onDaySelected(_selectedDate, _events[_selectedDate]));},
changed _onDaySelected method to:
(here i change selectedday variable to day recieved from calendar click and change state of selectedEvents, replacing them with total_events_map[key_which_is_selectedDay])
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
//dates are used with nulled time
_selectedDate = DateTime(day.year, day.month, day.day, 0, 0, 0);
setState(() {
_selectedEvents = _events[_selectedDate];
});
}
and changed _buildEventList() to this :
(so if selectedEvents are empty, it tells user so, if not, generates a list of items from selectedEvents)
Widget _buildEventList() {
if(_selectedEvents == null)
return ListView(
children: [
Card(
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(8.0),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(tr('nothing_planned'),
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
),
),
],
);
else return ListView(
children: _selectedEvents.reversed
.map((lecture) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.1),
// borderRadius: BorderRadius.circular(2.0),
color: hexToColor(lecture.color),
),
margin:
const EdgeInsets.symmetric(horizontal: 6.0, vertical: 1.5),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
lecture.start + " - " + lecture.end,
style: new TextStyle(
fontSize: 12.0,
color: Colors.black,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(lecture.lecture,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
onTap: () => displayDialog(lecture, context),
),
))
.toList(),
);
}