How to return Future<Widget> as Widget

2,414

Futures will have to have waited. In your case you're using futures in a rendering process, and since the process have started when you're waiting for the future due to the fact that the future is in the middle of the widget tree, you have to wait the future from the widget tree using some special method. You can use FutureBuilder for that.

Separate the data fetching and widget rendering and use FutureBuilder to await for the Future.

Future<Map<String, String>> getData() async {
  String displayName = await InformationFinder().getUserName(_auth);
  String provider = await ProviderFinder().getProvider(_auth);
  String profilePicture = await InformationFinder().getProfilePicture(_auth);

  return {
    'displayName': displayName,
    'provider': provider,
    'profilePicture': profilePicture
  };
}

Widget getCorrespondingPage(int index) {
  return FutureBuilder<Map<String, String>>(
    future: getData,
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        final displayName = snapshot.data['displayName'];
        final provider = snapshot.data['provider'];
        final profilePicture = snapshot.data['profilePicture'];

        bool isFromGoogleSignIn = provider == 'google';
        switch (index) {
          case 0:
            return SideBarLayoutStateful(
              app: SmartVetScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
            break;
          case 1:
            return SideBarLayoutStateful(
              app: SmartReminderScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
          default:
            return null;
        }
      }
    },
  );
}
Share:
2,414
XtremeDevX
Author by

XtremeDevX

I'm XtremeDevX, professional app developer, and I code Dart, Swift, And Python. I am currently learning Tensorflow and Keras for advanced Machine Learning.

Updated on December 13, 2022

Comments

  • XtremeDevX
    XtremeDevX over 1 year

    The code below might seem a bit complicated, though basically the function below uses a switch case to return the correct widget based on the index number of the navigation bar. The problem which i am facing, is that, when the body of the scaffold has to get the correct page according to the index number of the navigation bar, it tells me that i cannot have a type of Future <Widget> instead of a type of Widget as the body of my scaffold. I expected this to happen however, i do not know how to add the await keyword, so that the type is a valid widget. Thanks for your help. PS. Please see the comments, it tells where i want to call the function in the below code.

    Future<Widget> getCorrespondingPage(int index) async {
        bool isFromGoogleSignIn;
        String displayName = await InformationFinder().getUserName(_auth);
        String provider = await ProviderFinder().getProvider(_auth);
        String profilePicture = await InformationFinder().getProfilePicture(_auth);
        if (provider == 'Google') {
          setState(() {
            isFromGoogleSignIn = true;
          });
        } else {
          setState(() {
            isFromGoogleSignIn = false;
          });
        }
        switch (index) {
          case 0:
            return SideBarLayoutStateful(
              app: SmartVetScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
            break;
          case 1:
            return SideBarLayoutStateful(
              app: SmartReminderScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
          default:
            return null;
        }
      }
    

    This is my completed stateful widget:

    class _NavigationBarScreenState extends State<NavigationBarScreen> {
      int currentIndex = 0;
    //THIS IS WHERE THE ABOVE FUNCTION WAS CREATED
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              currentIndex: currentIndex,
              type: BottomNavigationBarType.shifting,
              iconSize: 27.0,
              elevation: 10.0,
              selectedFontSize: 18.0,
              unselectedFontSize: 15.0,
              items: [
                BottomNavigationBarItem(
                  icon: Icon(FontAwesomeIcons.stethoscope),
                  title: Text('Smart Vet'),
                  backgroundColor: Colors.green.shade200,
                ),
                BottomNavigationBarItem(
                  icon: Icon(FontAwesomeIcons.bell),
                  title: Text('Smart Remind'),
                  backgroundColor: Colors.purple.shade100,
                ),
              ],
              onTap: (index) {
                setState(() {
                  currentIndex = index;
                });
              },
            ),
    //THIS IS WHERE I NEED TO GET BACK THE WIDGET FROM THE getCorrespondingPage() method
            body: ,
          ),
        );
      }
    }
    
    
  • XtremeDevX
    XtremeDevX almost 4 years
    Thanks, though could you explain in more detail how that works?