flutter ignors alertdialog in catch if there is finally - flutter

writing an alertdialog inside a catch but if there is a finally it just ignores the alert dialog. the print just shows and escaping the dialog? and if I removed the finally it just works fine. help why this happening.
catch(error){
showDialog(context: context, builder: (ctx)=> AlertDialog(
title: Text("An ERROR accurred!"),
content: Text(error.toString()),
actions: [
FlatButton(onPressed: (){Navigator.of(ctx).pop();}, child: Text("OK"))
],
),
);
print(error.toString()+"from alert");
}
finally{
setState(() {
_isLoading = false;
});
Navigator.of(context).pop();
}
}

finally will be fired depending on any result.
How your code is working actually : First, catch is fired, showDialog is executed and dialog is shown, then print is executued. After these operation, finally section is exectued and Navigator.of(context).pop() pop (hide) your dialog. And since it is fast, you think your dialog is not shown.

The showDialog Widget also returns a Future so this means you need to use await until this code is executed before going to the finally block.
do it this way...
...
} catch (error) {
await showDialog<Null>(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Something whent wrong'),
content: const Text('An Error ocurred'),
actions: [
FlatButton(
child: const Text('Okay'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
);
} finally { ....

Related

Returning data from .pop() to use it anywhere

I have written a code that return bool type variables. Whether you like the movie. If you like the movie then it returns true, if you don't like the movie then it returns false. But since the .pop() method works in ElevatedButton, I cannot reach it from another class. How can I reach the value?
ElevatedButton(
child: Text(
"Go to new page"
),
onPressed: () async {
final answer = await Navigator.of(context).push<bool>(
MaterialPageRoute(
builder: (context) {
return VideoScreen("Did you like the video?");
},
)
);
},
),
However, I cannot say like:
ElevatedButton(
child: Text(
"Go to new page"
),
onPressed: () async {
final answer = await Navigator.of(context).push<bool>(
MaterialPageRoute(
builder: (context) {
return VideoScreen("Did you like the video?");
},
)
);
},
),
Text(answer)
],
);
So how can I reach that value? Callback or something? Thanks in advance
Use can pass value to parent route while pop like
Navigator.of(context).pop(YourValue);
While you push make sure to await.
final result = await Navigator.of(context)....;
print(result);

How to pop out double alert message

I am new to Flutter. I made my first pop out confirmation alert dialog (Figure 1) but I want to pop another alert dialog window after.
What I am trying to achieve, it's the following: after I click Yes (Figure 2) the app would lead me to my homescreen and pop out another alert dialog.
You could create a method for the second Alert to show up, and call it when you click "YES" on the first one.
void showSecond(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text("Thank you for paying with us"),
content: Icon(Icons.check_circle_outline),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Okay'),
),
],
),
);
}
and your onPressed() of "YES" in the first alert should look something like:
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => const SuccessPay()));
showSecond(context);
},
It was a bit hard to replicate your code from an image, so if something it's not accurate let me now. For the next time, post your code in a code block instead of a picture :)
you can call showAlertDialog to show second popup.(you can create new method to show second popup as content is different)This line can be added after
Navigator.of(context).pop() of first popup
You can use the .then() method. Call it if the user pressed the "YES" button.
Add value when poping your dialog like this Navigator.of(dialogCtx).pop(true);
showDialog(
context: context,
builder: (dialogCtx) => AlertDialog(
// title:
// content:
),
actions: [
TextButton(
onPressed: () {
Navigator.of(dialogCtx).pop(false);
},
child: const Text('CANCEL'),
),
TextButton(
onPressed: () {
Navigator.of(dialogCtx).pop(true);
},
child: const Text('YES'),
),
],
),
).then(
(value) => {
if (value == true)
{
// display the next dialog with the scaffolds context
},
},
);

Run a function AFTER that the alertbox has been dismissed

I already read countless links like this one but it does not help.
The use case is very simple, I want to run a function AFTER the alert box has been dismissed.
void dummyFunc() {
sleep(Duration(seconds:3));
print("done");
}
Future<bool> displayDialog() async {
return showDialog<bool>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('AlertDialog Title'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('This is a demo alert dialog.'),
Text('Would you like to approve of this message?'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Decline'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
FlatButton(
child: Text('Approve'),
onPressed: () {
Navigator.of(context).pop(true);
},
),
],
elevation: 24.0,
shape:RoundedRectangleBorder(),
);
},
);
}
var button = AnimatedOpacity(
opacity: 1.0,
duration: Duration(milliseconds: 500),
child: FloatingActionButton(
tooltip: 'Start',
child: Icon(iconShape),
onPressed: () async {
bool shouldUpdate = await displayDialog();
print(shouldUpdate);
if (shouldUpdate)
dummyFunc();
})
);
But the alert dialog is dismissed 3sd after.
Kindly let me know what I am doing wrong, Thank you~
I think this is happening because you are using sleep. Instead of that use Future delay.
void dummyFunc() {
print("done");
}
If you don't want delay, then you can also remove this future, this function will executed after dialog box dismissed.
Sleep will hold the process, that’s why you are facing this error.
Solved it thanks to Viren who gave me a good intuition, Timer works also nicely if you are not using a loop:
void dummyFunc() {
Timer(Duration(seconds: 3), () {
print("done");
});
}
Edit: Actually Viren's answer work better with loops! This can work also. Just avoid sleep. Spent 3h on this, now I hate sleep().

How to close an Alert dialog without a button in FLUTTER

I want to show a circle indicator when the user presses the login button. But sometimes an error can occur such as a Wrong email or wrong password. In that case, the circle indicator should be stopped and the error message should be shown. There is no button in circle indicator alert dialog. I want it to automatically close when an error found
onPressed: () async {
AuthResult user;
progressIndi();
try {
user = await _auth.signInWithEmailAndPassword(email: email, password: pass);
} catch (err) {
finderror(err.code);
}
finderror function will find the error message to show.
progressIndi() function will show the alert dialog. I tried to implement it with stacks. But it's only showing changes when I close the dialog box and press the login button again.
void progressIndi() {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return IndexedStack(
index: isError,
children: <Widget>[
AlertDialog(
content: new Row(
children: [
CircularProgressIndicator(),
Container(
margin: EdgeInsets.only(left: 5),
child: Text(" Loading")),
],
),
),
AlertDialog(
title: Text("Error Found"),
content: Text(errorMessage),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Try Again"),
onPressed: () {
Navigator.of(context).pop();
isError = 0;
},
),
],
),
],
);
},
);
}
I know that alert dialog can be closed using the button and Navigator.of(context).pop() .
Please, anyone, give me a hint to close the alert dialog from outside without a button.
You can remove the dialog when an error occurs by calling Navigator.of(context).pop() just after the exception occurs and then show another dialog for error. Hope this helps.
AuthResult user;
progressIndi();
try {
user = await _auth.signInWithEmailAndPassword(email: email, password: pass);
} catch (err) {
//Use pop here.
Navigator.of(context).pop();
//make findError open another dialog.
finderror(err.code);
}

Flutter SnackBar or Toast show only after each Hot Reload

when i use this method to resolve
setState() or markNeedsBuild() called during build problem
issue, SnackBar, EdgeAlert, Toast don't show on multiple click on FloatingActionButton but, after each Hot Reload, theme appear on screen,
_onWidgetDidBuild(Function callback) {
WidgetsBinding.instance.addPostFrameCallback((_) {
callback();
});
}
for example:
body: Builder(
builder: (scaffoldContext) => Column(children: <Widget>[
Container(
child: Text('aaa'),
),
BindingWidget<_HomePageViewModel>(
bindings: <Binding>[
Binding('registerStatus', bindableBase,
_HomePageViewModel.registerStatusProperty,
bindingDirection: BindingDirection.TwoWay,
valueConverter: _NumberValueConverter())
],
builder: (bc) {
_onWidgetDidBuild(() {
var registerStatus =
BindingWidget.of<_HomePageViewModel>(bc)
.getValue('registerStatus') as String;
print('2) $registerStatus');
switch(int.parse(registerStatus)){
case 1:
EdgeAlert.show(context, title: 'Title', description: 'Description', gravity: EdgeAlert.TOP);
/*
Scaffold.of(scaffoldContext).showSnackBar(
SnackBar(
content: Text('dddddd'),
backgroundColor: Colors.red,
),
);*/
/* Toast */
break;
}
});
return Container();
}),
])),
how can i resolve this problem for this implementation my code?
thanks in advance