Home > Blockchain >  Can't use a future string to determine initalRoute
Can't use a future string to determine initalRoute

Time:06-04

My code is like this

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  Future<String> validation() async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isWTdone = prefs.getBool('WT') ?? false;
    bool isLoggedIn = prefs.getString('email') == null ? false : true;

    if(isWTdone){
      if(isLoggedIn)
      {
        return '/home';
      }
        return '/login';
    }
      return '/';
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [
        locator<AnalyticsService>().getanalyticsObserver(),
      ],
      //iswalkthrough and islogin
      initialRoute: validation(),
      routes: appRoutes,
    );
  }
}

in the initalRoute line it gives me this error:

The argument type 'Future' can't be assigned to the parameter type 'String?'.

Can anyone know how can i fix this? my goal is to determine the initalRoute from the output of the SharedPreference

CodePudding user response:

Try to wrap MaterialApp to FutureBuilder or perform your async code in main.dart before calling runApp. You can pass needed value to the MyApp through the constructor.

CodePudding user response:

Yup, that's because the method validation is a future and to use it you have to write await validation() and that cannot be done directly inside the widget tree, a solution I suggest;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final prefs = await SharedPreferences.getInstance();
  bool isWTdone = prefs.getBool('WT') ?? false;
  bool isLoggedIn = prefs.getString('email') == null ? false : true;
  late final initialRoute;

  if (isWTdone) {
    if (isLoggedIn)
      initialRoute = '/home';
    else
      initialRoute = '/login';
  } else
    initialRoute = '/';

  return runApp(MyApp(initialRoute: initialRoute));
}

class MyApp extends StatelessWidget {
  final String initialRoute;

  const MyApp({Key? key, required this.initialRoute}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [
        locator<AnalyticsService>().getanalyticsObserver(),
      ],
      //iswalkthrough and islogin
      initialRoute: validation(),
      routes: appRoutes,
    );
  }
}

What I've done here, is I initialized the initialRoute before the runApp and passed to the MyApp Stateless Widget

CodePudding user response:

Set the initialRoute to a route of a Splash Screen. Inside that screen you should call your validation() function inside initState and depending on your output you navigate to whatever screen you want to. I don't think using an async method inside your MaterialApp widget is encouraged so try to implement this inside a Splash Screen and you'll be fine.

  • Related