Hey I have an ElevatedButton with an onPressed. Inside the onPressed are some if-statements that ensure that everything is correct and afterwards I want to push these information to firebase. How can I leave the onPressed function if a condition is not fulfilled? I tried return and return null, return 0 but my App is just freezing.
ElevatedButton(
onPressed: () async {
if (date != null) {
print(date);
} else {
dialog.showAlertDialog(context, 'Oops', 'You didn\'t choose a date!');
return;
}
if (time != null) {
print(time);
} else {
dialog.showAlertDialog(context, 'Oops', 'You didn\'t choose a time!');
return 0;
}
if(combinedDateAndTime.isBefore(DateTime.now())) {
dialog.showAlertDialog(context, 'Oops', 'Your date and time is in the past');
return null;
}
_firestore.collection('foo').add({
'dateTime': combinedDateAndTime,
});
},
style: raisedButtonStyle,
),
),
I just couldn't figure out how to leave the function. I would appreciate any help.
one way is that define a boolean variable and check if it is true then firestore.collection called, somthing like this :
bool var = true;
if (date != null) {
print(date);
} else {
dialog.showAlertDialog(context, 'Oops', 'You didn\'t choose a date!');
var = false;
}
if (time != null) {
print(time);
} else {
dialog.showAlertDialog(context, 'Oops', 'You didn\'t choose a time!');
var = false;
}
if(combinedDateAndTime.isBefore(DateTime.now())) {
dialog.showAlertDialog(context, 'Oops', 'Your date and time is in the past');
var = false;
}
if (var == true){
_firestore.collection('foo').add({
'dateTime': combinedDateAndTime,
});
}
Related
So for some background, I implemented a function that reads from Firebase's real-time database and returns a child node. I have built a button that is meant to check if that function returns the object or null if the function returns an object I want the snack bar to display a message.
ElevatedButton(
onPressed: () {
if (validateUsername() != null) {
print("conditional: test");
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
"Username has been taken please try a different one"),
duration: Duration(seconds: 5)));
} else {
return null;
}
},
I had some success with the function by turning it into an async function
validateUsername() async {
final database = FirebaseDatabase.instance.ref().child("/takenUsernames");
await database
.child(_usernameController.text.trim())
.once()
.then((DatabaseEvent event) {
final snapShot = event.snapshot;
final value = snapShot.value;
print("function result: $value");
return value;
});
}
When I turn it to an async function the snack bar displays the message but unfortunately even when the conditional is equal to a null, it for some reason continues to display the message and prints the "test"output. But if I were to try taking away the async the snack bar doesn't print and the "test" in the conditional doesn't print.non-async output
Any help would be appreciated and thanks for your time.
Try this approach, using the await in a variable will wait for the value then the if will evaluate what the result.
ElevatedButton(
onPressed: () async {
String validation = await validateUsername(); // I used type String but you should use the type that will be return.
if (validation != null) {
print("conditional: test");
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
"Username has been taken please try a different one"),
duration: Duration(seconds: 5)));
} else {
return;
}
},
)
add try/catch
validateUsername() async {
try {
final database = FirebaseDatabase.instance.ref().child("/takenUsernames");
await database
.child(_usernameController.text.trim())
.once()
.then((DatabaseEvent event) {
final snapShot = event.snapshot;
final value = snapShot.value;
print("function result: $value");
return value;
});
} catch(e) {
print("err $e");
return null;
}
}
Thanks to some help from #WilsonToribio, I was able to use the information he gave and also implement a few changes to the validateUsername() function
as seen here
validateUsername() async {
try {
final database = FirebaseDatabase.instance.ref().child("/usernames");
final response = await database
.child(_usernameController.text.trim())
.once()
.then((event) {
final dataSnapshot = event.snapshot;
if (dataSnapshot.value != null) {
return dataSnapshot.value;
}
});
return response;
} catch (e) {
print("err $e");
return null;
}
}
I want to call the onTap functionality outside of my button. As soon as I receive my OTP, I want to call the onTap of my manually created widget. I have a custom widget called as LoginCTA and I want to call it's onTap after I receive my OTP in initSmsListener method which I called in initState.
My code -
String _comingSms = 'Unknown';
Future<void> initSmsListener() async {
String comingSms;
try {
comingSms = await AltSmsAutofill().listenForSms??"";
} on PlatformException {
comingSms = 'Failed to get Sms.';
}
if(!mounted)
return;
setState(() {
_comingSms=comingSms;
print("\n \n \n Coming SMS - $_comingSms");
otpController.text = _comingSms[23] + _comingSms[24] + _comingSms[25] + _comingSms[26]
+ _comingSms[27] + _comingSms[28];
});
//Apply here -
}
#override
void initState() {
initSmsListener();
super.initState();
}
isOTP
? LoginCTA(
//After input otp
onPressed: () async {
print(Provider.of<APIData>(context, listen: false)
.loggedIN);
if (emailEntered &&
otpController.text.length == 6) {
bool res;
try {
res = await widget.signInWithOTP(
contactController.text, otpController.text);
} catch (e) {
res = false;
print(e);
}
if (res) {
Fluttertoast.showToast(
msg: "Verifying OTP...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
textColor: cardColor,
backgroundColor: primaryTextColor,
fontSize: 16.0,
);
Timer(Duration(seconds: 2), () {
print(Provider.of<APIData>(context,
listen: false)
.loggedIN);
if (Provider.of<APIData>(context,
listen: false)
.loggedIN ==
1) {
Navigator.pop(context);
}
});
}
}
},
btnText: otpButtonText,
isDisabled: isDisabled,
)
: LoginCTA(
//After input mobile number
onPressed: () async {
if (emailEntered &&
contactController.text.length == 10) {
widget.sendOTP(contactController.text);
setState(() {
isOTP = true;
isDisabled = true;
});
} else {
print('kuch na kuch glti');
}
},
btnText: buttonText,
isDisabled: isDisabled,
hasIcon: hasIcon,
),
Just extract the functionality out into its own function. Then you can assign the function to onTap and also call it whenever you like.
I am trying to work on a project and I am fairly new to Flutter.
I have this DropdownButtonFormField<ClassNoSearch> and value is _currentClassNoSearch that is an object ClassNoSearch _currentClassNoSearch;
After I choose an item from this list, _getData(); function is called and it sets the _currentClassNoSearch; to null.
I don't want this to happen, instead, I want the chosen value to be the same after _getData(); but I can't seem to delete the _currentClassNoSearch = null; line.
DropdownButtonFormField<ClassNoSearch> :
DropdownButtonFormField<ClassNoSearch>(
hint: Text("Hint"),
isExpanded: true,
value: _currentClassNoSearch,
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
),
icon: Icon(
Icons.arrow_drop_down,
),
onChanged: (ClassNoSearch newVal) {
setState(() {
_currentClassNoSearch = newVal;
});
_getData();
},
_getData();
Future<HomeworkSudo> _getData() {
if (_currentClassNoSearch == null) {
return getHomeworkSudo("").then((HomeworkSudo result) {
setState(() {
activeHomeworkList = result.activeHomeWork;
inactiveHomeworkList = result.passivHomeWork;
classNoList = result.classNo;
});
return result;
});
} else {
return getHomeworkSudo(_currentClassNoSearch.userClassDepartmentId)
.then((HomeworkSudo result) {
setState(() {
_currentClassNoSearch = null;
activeHomeworkList = result.activeHomeWork;
inactiveHomeworkList = result.passivHomeWork;
classNoList = result.classNo;
});
return result;
});
}
}
As you can see If I delete the line that sets _currentClassNoSearch = null; i get the error below . Any ideas on how I should approach this?
items == null || items.isEmpty || value == null
Either zero or 2 or more DropdownMenuItems were detected with the same value.
The code says the following assertion failed:
items == null || items.isEmpty || value == null
You don't include items in your code, so items is set to null by default, which is why the assertion fails.
I am trying to implement a flutter app to fetch data from an API end point. I've already implemented the fetch function on button press.
Although, I want the button (Enregistrer) to get disabled (to avoid multiple clicks) while the request is being fetched or after success editing (name, adress ...) !
I implemented it using the dart http package.
Here's my code for the same:
Container(
margin: EdgeInsets.symmetric(
vertical: 10),
width: size.width * 0.4,
child: ElevatedButton(
onPressed: () {
if (_nameController.text ==
"" &&
_emailController.text ==
"" &&
_adressController
.text ==
"") {
setState(() =>
isButtonDisabled =
true);
} else {
editUserProfile();
}
},
child: Text('Enregistrer'),
void editUserProfile() async {
setState(() {});
// if (_formKey.currentState.validate()) {
String name = _nameController.text;
String email = _emailController.text;
String adress = _adressController.text;
userApi.editUserProfile(name, email, adress).then((data) {
if (data != null) {
}
setState(() {
enableup = false;
enableadress = false;
enableemail = false;
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(data)));
// ScaffoldMessenger.of(context).showSnackBar(snackBar3);
}).catchError((error) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(error.toString())));
});
setState(() {});
}
if you set null onPressed you actualy disable the click
onPressed: isButtonDisabled ? null : () {
if (_nameController.text == "" &&
_emailController.text == "" &&
_adressController.text == "") {
setState(() =>
isButtonDisabled = true);
} else {
editUserProfile();
}
}
I am trying to put an if statement inside another like this :
void initState() {
super.initState();
FirebaseAuth.instance.currentUser().then((res) {
if (res != null) {
if (userType.text == 'Student') {
Navigator.pushReplacementNamed(context, '/StudentsPage');
} else if (userType.text == 'Teacher') {
Navigator.pushReplacementNamed(context, '/TeacherPage');
} else if (userType.text == 'Admin') {
Navigator.pushReplacementNamed(context, '/AdminPage');
}
} else {
LoginScreen();
}
});
}
But It gives me this error that there is a text that was called on null, so if anyone has an idea.
I'm using FireBase database.. and I am retrieving the data using this:
void getUserData() async {
try {
firestoreInstance .collection('Users') .document(usernameController.text) .get() .then((value) {
setState(() {
email = (value.data)['email'];
password = (value.data)['password'];
gender = (value.data)['gender'];
username = (value.data)['username'];
userType = (value.data)['userType'];
}); });
print('$userType');
}
catch (e) {
print(e.toString);
} }
The issue is that userType is a String object and therefore has no text getter method. Remove the .text and it seems that your code would work fine.
if (res != null) {
if (userType == 'Student') {
Navigator.pushReplacementNamed(context, '/StudentsPage');
} else if (userType == 'Teacher') {
Navigator.pushReplacementNamed(context, '/TeacherPage');
} else if (userType == 'Admin') {
Navigator.pushReplacementNamed(context, '/AdminPage');
}
}