devsin
devsin

Reputation: 155

How to show a dialog with FutureBuilder when press a button?

I upload an image FirebaseStorage with FutureBuilder and when I press upload button I want to show a waiting dialog. Image upload successfully on FireStorage but nothing shows up. Whats wrong my codes? I think FutureBuilder return Widget and press button void. Maybe it is the problem. Or I am calling FutureBuilder wrong way. Do you have any tips or suggestions for my wrong code?

Here is my code;



    Widget buildBody(BuildContext context) {
        return new SingleChildScrollView(
          child: new Column(
            children: [
              new SizedBox(
                width: double.infinity,
                child: new RaisedButton(
                  child: new Text('Upload'),
                  onPressed:  () {
                    futureBuilder();
                  },
                ),
              ),
            ],
          ),
        );
      }

     Future mediaUpload() async {
        final fileName = DateTime.now().millisecondsSinceEpoch.toString() + '.jpg';
        final StorageReference storage = FirebaseStorage.instance.ref().child(fileName);
        final StorageUploadTask task = storage.putFile(_image);
        return task.future;
      }

      Widget futureBuilder() {
        return new FutureBuilder(
          future: mediaUpload(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                print('ConnectionState.none');
                return new Text('Press button to start.');
              case ConnectionState.active:
                print('ConnectionState.active');
                return new Text('');
              case ConnectionState.waiting:
                waitingDialog(context);
                return waitingDialog(context);
              case ConnectionState.done:
                print('ConnectionState.done');
                if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
                print(snapshot.data.downloadUrl);
                Navigator.of(context).pushReplacementNamed('home');
                return new Text('Result: ${snapshot.data.downloadUrl}');
            }
          },
        );
      }

      waitingDialog(BuildContext context) {
        return showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return new Center(
              child: new SizedBox(
                width: 40.0,
                height: 40.0,
                child: const CircularProgressIndicator(
                  value: null,
                  strokeWidth: 2.0,
                ),
              ),
            );
          },
        );
      }

Upvotes: 2

Views: 3579

Answers (1)

Dinesh Balasubramanian
Dinesh Balasubramanian

Reputation: 21758

I am not 100% sure why FutureBuilder is not working. But I have a guess. In the above example, FutureBuilder is not attached to the widgetTree(screen). Not attached means value returned from FutureBuilder is not displayed in screen. In this case, Text is returned based on snapshot.connectionState which is not attached to screen.

Work around: (I tested and it worked, can you please verify)

futureBuilder(BuildContext context) {
  mediaUpload().then((task) {          // fire the upload
    Navigator.of(context).maybePop();  // remove the dialog on success upload
  });                                  // we can use task(which returned from
                                       // mediaUpload()) to get the values like downloadUrl.
  waitingDialog(context);             // show the spinner dialog
}

Upvotes: 1

Related Questions