Home > Mobile >  showModalBottomSheet not returning value when you are using it in a method
showModalBottomSheet not returning value when you are using it in a method

Time:10-06

I am having a String that is supposed to be returned after clicking a button in a Future showModalBottomSheet. Below is how i how i am implementing it and how it is working


 onPressed: () async {


 String? returnString = await showModalBottomSheet<String>(
                                        context: context,
                                        isDismissible: false,
                                        builder: (ctx) {
                                          return StatefulBuilder(builder: (ctx, setState) {
                                            return Container(
                                              margin: EdgeInsets.all(10),
                                              padding: EdgeInsets.all(10),
                                              child: ElevatedButton(
                                                onPressed: (){
                                                  Navigator.pop(ctx, "This is return string bla bla bla");
                                                },
                                                child: Text("Click Me To Return"),
                                              ),
                                            );
                                          });
                                        },
                                      );

                                      Logger().i("PrintReturnString: $returnString");
                                      Logger().i("PrintReturnStringRunTimeType: ${returnString.runtimeType}");

}

But because i want to use this in several places and i did not want to repeat myself and rewrite the code every time in other classes that would be redundant i decided to try implementing this using a global method but its not working it just returns null instead of String

This is return string bla bla bla

Below is how i have tried implementing it using a method that i can call anywhere in the class


showReturnStringBottomSheet(ctx) async {
  await showModalBottomSheet<String>(
      context: ctx,
      shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
      elevation: 5,
      isDismissible: true,
      isScrollControlled: true,
      builder: (ctx) {
        return StatefulBuilder(builder: (ctx, setState) {
          return Container(
            margin: EdgeInsets.all(10),
            padding: EdgeInsets.all(10),
            child: ElevatedButton(
              onPressed: (){
                Navigator.pop(ctx, "This is return string bla bla bla");
              },
              child: Text("Click Me To Return"),
            ),
          );
        });
      });
}

Below is how i am calling the method


 onPressed: () async {

    String? returnString = await showReturnStringBottomSheet(context);

 }

Is there something that i am doing wrong because its just working when i put the method directly insde onPressed but it stops working when i use a global method

CodePudding user response:

You can pass the String outside your modal bottom sheet for example:

class _MyHomePageState extends State<MyHomePage> {
  String? text;

  Future<void> _openBottomSheet() async {
    final value = await _myBottomSheet();
    setState(() {
      text = value;
    });
  }

  Future<String?> _myBottomSheet() async {
    String? value;

    await showModalBottomSheet<void>(
      context: context,
      builder: (context) => Center(
        child: TextButton(
          onPressed: () {
            value = 'Hello world!';
            Navigator.pop(context);
          },
          child: const Text('Say hello!'),
        ),
      ),
    );

    return value;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: text?.isNotEmpty == true
            ? Text(text!)
            : const Text('Bottom sheet example'),
      ),
      body: Center(
        child: TextButton(
          onPressed: _openBottomSheet,
          child: const Text('Open bottom sheet'),
        ),
      ),
    );
  }
}

CodePudding user response:

showModalBottomSheet is an async method so you should wait for it then it makes your showReturnStringBottomSheet a future function ,Try this:

Future<String?> showReturnStringBottomSheet(ctx) async {
    var result = await showModalBottomSheet<String>(
        context: ctx,
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
        elevation: 5,
        isDismissible: true,
        isScrollControlled: true,
        builder: (ctx) {
          return StatefulBuilder(builder: (ctx, setState) {
            return Container(
              margin: EdgeInsets.all(10),
              padding: EdgeInsets.all(10),
              child: ElevatedButton(
                onPressed: () {
                  Navigator.pop(ctx, "This is return string bla bla bla");
                },
                child: Text("Click Me To Return"),
              ),
            );
          });
        });
    return result;
  }

and use it like this:

onPressed: () async {

   String? returnString = await showReturnStringBottomSheet(context);
   if(returnString != null){
      print("returnString = $returnString");
   }
 }

CodePudding user response:

The problem is you forgot to return here:

showReturnStringBottomSheet(ctx) async {
  await showModalBottomSheet<String>(

change it to :

//Add Future<String?> here to make code cleaner
Future<String?> showReturnStringBottomSheet(ctx) { 
  return showModalBottomSheet<String>(
  • Related