How to pass agruments (id) to dialog in flutter - flutter

well, my problem is when i use navigator i cannot open alert-dialog, on the same screen and when i use showDialog i dont have my 'book-detail' as argument. please help..
My Code :
leading: GestureDetector(
onTap: () {
// Navigator.of(context)
// .pushNamed(BookUpdate.routename, arguments: widget.bookId);
showDialog(
context: context,
builder: (BuildContext context) {
return BookUpdate();
},
);
},

Related

Flutter, break out private method to a helper class. Arguments problem

I would like to break out this method and make it public in a helper class but I run into this error when trying and passing context to it? It wants two required contexts and BuildContext but I don't know how to implement this? I get this error. It seems to be a problem with two context arguments also:
"2 positional arguments required but found 0. Try to add missing arguments"
Or if I type the first context it is:
"1 positional argument required but found 0. Try to add missing arguments"
Private method:
_showDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Title'),
content: Text('Body'),
actions: <Widget>[
OutlinedButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Public method (with two context arguments):
class _LegendScreenState extends State<LegendScreen> {
showDialog(context, BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Title'),
content: Text('Body'),
actions: <Widget>[
OutlinedButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
The issue is coming because, you are defining showDialog method that is already defined on material.dart. It is overlapping with name. Try to rename the helper class something else like appDialog and pass context.
appDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
More about showDialog
Remove one context argument. You only need one.
showDialog(context, BuildContext context) {
should be:
showDialog(BuildContext context) {

Call widget in Future<Widget> function Flutter

Basically I have a button(GestureDetector) which to call Future function in the same file. The thing is the widget in that function does not appear as it should but the background process is successfully running.
The trigger:
showDialog(
context: context,
builder: (context) {
AlertDialog(
/// Below the button to call function *resetPassword*
GestureDetector(
child: Text("Yes"),
onTap: () async {
Navigator.of(context).pop();
resetPassword('manan#gmail.com')}))})
The widget function:
Future<Widget> resetPassword(email) async {
try{
await FirebaseAuth.instance.sendPasswordResetEmail(email: email)
return AlertDialog(
///the content of dialog)
}on FirebaseAuthException catch (e) {
return AlertDialog(
///the content of dialog)
}}
Surprisingly the email of reset password was successfully sent.
Disclaimer: I am new to Flutter, hopefully sifus can considerate it.
When you're working with dialogs in general you have to wrap it with showDialog() method, like:
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Center(child: Text('Reset password')),
content: Builder(
builder: (context) {
return Container(child: ForgotPasswordForm());
},
),
);
},
);
Secondly, I see that you have nested Alert Dialog widgets and I think you should restructure this.

How to dismissed showDialog with backBoutton?

I have a showDialog called inside FloatingActionButton, I want to dismiss the showDialog when the back button is clicked, but it is returned to the previous page without dismiss
MyCode
FloatingActionButton(
onPressed: () async {
await showDialog(
context: context,
// useRootNavigator: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Dialog"),
........)
Because you are passing the wrong context of the page. I had the same issue today i solved it by doing
FloatingActionButton(
onPressed: () async {
await showDialog(
context: context,
// useRootNavigator: false,
builder: (BuildContext dialogContext) {
return AlertDialog(
title: Text("Dialog"),
........)
and then i popped the dialog with the dialogContext
Navigator.of(dialogContext).pop();

Flutter dialog not closing completely

We have a Flutter dialog that when we click Ok and it sends the user home... the dialog lingers on the screen even after sending them home and then goes away which is annoying.
Here is the code for the dialog:
Future<void> _requestSupportDialog(BuildContext context, User user, Features features) {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Success! You have been entered into the support queue'),
content: const Text('Support it on its way'),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
// Send them HOME.
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new FlutterReduxApp(user: user, features: features)));
},
),
],
);
},
);
}
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context)=>Home(son: 0,)));
Before pushing to a new route, try to pop first to dismiss the dialog.
Navigator.of(context).pop()
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context)=>Home(son: 0,)));

How to show a dialog inside a futurebuilder?

I want to show a dialog if I receive an error in a futurebuilder.
If I receiver an error, I want to show a dialog and force the user to click on the button, so that he can be redirected to another page.
The problems seems to be that it is not possible to show a dialog while widget is being built.
FutureBuilder(
future: ApiService.getPosts(),
builder: (BuildContext context, AsyncSnapshot snapShot) {
if (snapShot.connectionState == ConnectionState.done) {
if (snapShot.data.runtimeType == http.Response) {
var message =
json.decode(utf8.decode(snapShot.data.bodyBytes));
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text("Ok"),
onPressed: () => null",
)
],
);
});
}
return ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return Divider(
color: Colors.grey,
height: 1,
);
},
itemBuilder: (BuildContext context, int index) {
return _buildPostCard(index);
},
itemCount: snapShot.data.length,
);
return Center(
child: CircularProgressIndicator(),
);
},
)
If I return the AlertDialog alone, it works. But I need the showDialog because of the barrierDismissible property.
Does any one know if that is possible?
Also, is this a good way to handle what I want?
Thanks
UPDATE
For further reference, a friend at work had the solution.
In order to do what I was looking for, I had to decide which future I was going to pass to the futureBuilder.
Future<List<dynamic>> getPostsFuture() async {
try {
return await ApiService.getPosts();
} catch (e) {
await showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text("Ok"),
onPressed: () => null",
)
],
);
});
}
}
}
Then in the futureBuilder I would just call
FutureBuilder(
future: getPostsFuture(),
Thanks
To avoid setState() or markNeedsBuild() called during build error when using showDialog wrap it into Future.delayed like this:
Future.delayed(Duration.zero, () => showDialog(...));
setState() or markNeedsBuild() called during build.
This exception is allowed because the framework builds parent widgets before its children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
So to avoid that Future Callback is used, which adds a call like this EventQueue.
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Future futureCall() async {
await Future.delayed(Duration(seconds: 2));
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: futureCall(),
builder: (_, dataSnapshot) {
if (dataSnapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
Future(() { // Future Callback
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Employee Data'),
content: Text('Do you want to show data?'),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.of(context).pop('No'),
child: Text('NO')),
FlatButton(
onPressed: () =>
Navigator.of(context).pop('Yes'),
child: Text('YES'))
],
));
});
return Container();
}
},
);
}
}
The builder param expects you to return a Widget. showDialog is a Future.
So you can't return that.
You show Dialog on top of other widgets, you can't return it from a build method that is expecting a widget.
What you want can be implemented the following way.
When you receive an error, show a dialog on the UI and return a Container for the builder. Modify your code to this:
if (snapShot.data.runtimeType == http.Response) {
var message =
json.decode(utf8.decode(snapShot.data.bodyBytes));
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text("Ok"),
onPressed: () => null",
)
],
);
});
return Container();
}