title: Flutter Error Where Future Already Completed
body: <p>I'm having trouble figuring out an error of 'Bad state: Future already completed'. I basically have an app that uses a BottomNavigationBar and on one of my screens I am using this class that uses the Completer class.</p>
  
  <p>It happens when creating the webview again:</p>
  
  <pre><code>      body: WebView(
          initialUrl: 'https://www.google.com/',
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
          },
        )
  </code></pre>
  
  <p>Everything loads fine on the first view but if you select another BottomNavigationBarItem and then go back to the class, I get an Exception of Bad state: Future already completed. Below is full code.</p>
  
  <pre><code>import 'package:flutter/material.dart';
  import 'package:webview_flutter/webview_flutter.dart';
  import 'package:url_launcher/url_launcher.dart';
  import 'dart:async';
  
   class myClass extends StatelessWidget {
    Completer&lt;WebViewController&gt; _controller = Completer&lt;WebViewController&gt;();
    final Set&lt;String&gt; _favorites = Set&lt;String&gt;();
  
  @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          actions: &lt;Widget&gt;[
            NavigationControls(_controller.future),
            Menu(_controller.future, () =&gt; _favorites),
          ],
        ),
        //EXCEPTION OCCURS HERE
        //BAD STATE: FUTURE ALREADY COMPLETED
        body: WebView(
          initialUrl: 'https://www.google.com/',
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
          },
        ),
        floatingActionButton: _bookmarkButton(),
      );
    }
  
    _bookmarkButton() {
      return FutureBuilder&lt;WebViewController&gt;(
        future: _controller.future,
        builder:
            (BuildContext context, AsyncSnapshot&lt;WebViewController&gt; controller) {
          if (controller.hasData) {
            return FloatingActionButton(
              onPressed: () async {
                var url = await controller.data.currentUrl();
                _favorites.add(url);
                Scaffold.of(context).showSnackBar(
                  SnackBar(content: Text('Saved $url for later reading.')),
                );
              },
              child: Icon(Icons.favorite),
            );
          }
          return Container();
        },
      );
    }
  }
  
  class Menu extends StatelessWidget {
    Menu(this._webViewControllerFuture, this.favoritesAccessor);
    final Future&lt;WebViewController&gt; _webViewControllerFuture;
    final Function favoritesAccessor;
  
    @override
    Widget build(BuildContext context) {
      return FutureBuilder(
        future: _webViewControllerFuture,
        builder:
            (BuildContext context, AsyncSnapshot&lt;WebViewController&gt; controller) {
          if (!controller.hasData) return Container();
          return PopupMenuButton&lt;String&gt;(
            onSelected: (String value) async {
              if (value == 'Email link') {
                var url = await controller.data.currentUrl();
                await launch(
                    'mailto:?subject=hello&amp;body=$url');
              } else {
                var newUrl = await Navigator.push(context,
                    MaterialPageRoute(builder: (BuildContext context) {
                  return FavoritesPage(favoritesAccessor());
                }));
                Scaffold.of(context).removeCurrentSnackBar();
                if (newUrl != null) controller.data.loadUrl(newUrl);
              }
            },
            itemBuilder: (BuildContext context) =&gt; &lt;PopupMenuItem&lt;String&gt;&gt;[
                  const PopupMenuItem&lt;String&gt;(
                    value: 'Email link',
                    child: Text('Email link'),
                  ),
                  const PopupMenuItem&lt;String&gt;(
                    value: 'See Favorites',
                    child: Text('See Favorites'),
                  ),
                ],
          );
        },
      );
    }
  }
  
  class FavoritesPage extends StatelessWidget {
    FavoritesPage(this.favorites);
    final Set&lt;String&gt; favorites;
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(title: Text('Favorite pages')),
        body: ListView(
            children: favorites
                .map((url) =&gt; ListTile(
                    title: Text(url), onTap: () =&gt; Navigator.pop(context, url)))
                .toList()),
      );
    }
  }
  
  class NavigationControls extends StatelessWidget {
    const NavigationControls(this._webViewControllerFuture)
        : assert(_webViewControllerFuture != null);
    final Future&lt;WebViewController&gt; _webViewControllerFuture;
    @override
    Widget build(BuildContext context) {
      return FutureBuilder&lt;WebViewController&gt;(
        future: _webViewControllerFuture,
        builder:
            (BuildContext context, AsyncSnapshot&lt;WebViewController&gt; snapshot) {
          final bool webViewReady =
              snapshot.connectionState == ConnectionState.done;
          final WebViewController controller = snapshot.data;
          return Row(
            children: &lt;Widget&gt;[
              IconButton(
                icon: const Icon(Icons.arrow_back_ios),
                onPressed: !webViewReady
                    ? null
                    : () =&gt; navigate(context, controller, goBack: true),
              ),
              IconButton(
                icon: const Icon(Icons.arrow_forward_ios),
                onPressed: !webViewReady
                    ? null
                    : () =&gt; navigate(context, controller, goBack: false),
              ),
            ],
          );
        },
      );
    }
  
    navigate(BuildContext context, WebViewController controller,
        {bool goBack: false}) async {
      bool canNavigate =
          goBack ? await controller.canGoBack() : await controller.canGoForward();
      if (canNavigate) {
        goBack ? controller.goBack() : controller.goForward();
      } else {
        Scaffold.of(context).showSnackBar(
          SnackBar(
              content: Text("No ${goBack ? 'back' : 'forward'} history item")),
        );
      }
    }
  }
  </code></pre>