jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.32k stars 1.62k forks source link

A value of type 'GetRoute' can't be returned from method 'generateRoute' because it has a return type of 'Route<dynamic>'. #86

Closed Jethro87 closed 4 years ago

Jethro87 commented 4 years ago

Hi there. Great library, thank you!

Today I upgraded from Get 2.0.10 to 2.2.8 on flutter stable version 1.17.0, and have come across this error A value of type 'GetRoute' can't be returned from method 'generateRoute' because it has a return type of 'Route<dynamic>'.

I'm using onGenerateRoute. Here is a sample of my code:

main.dart

GetMaterialApp(
          navigatorObservers: <NavigatorObserver>[
            locator<AnalyticsService>().observer
          ],
          navigatorKey: Get.key,
          initialRoute: Routes.startupView,
          onGenerateRoute: Router.generateRoute,

router.dart

class Router {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case Routes.aboutUsView:
        return GetRoute(
          settings: settings,
          page: AboutUsView(),
        );

      case Routes.accountView:
        return GetRoute(
          settings: settings,
          page: AccountView(),
        );

      case Routes.entryView:
        final EntryViewArguments args = settings.arguments;
        return GetRoute(
          settings: settings,
          page: EntryView(
            entry: args.entry,
            index: args.index,
            isNew: args.isNew ?? false,
            isReviewing: args.isReviewing ?? false,
          ),
          fullscreenDialog: args.fullScreen ?? false,
        );
}
}

I've noticed that your documentation used to give a code sample for onGenerateRoute, but has switched to using namedRoutes. Is onGenerateRoute still a reasonable solution?

Thanks for your help.

jonataslaw commented 4 years ago

Hi, thanks for opening this issue. First of all, I would like to recommend that you do not use onGenerateRoute. I had to refactor Get and create the namedRoutes property to fix a multitude of errors in the Dev and master version. So, you can use this syntax:

GetMaterialApp(
          navigatorObservers: <NavigatorObserver>[
            locator<AnalyticsService>().observer
          ],
         // since 2.0 Get.key It is no longer necessary
          initialRoute: Routes.startupView,
          namedRoutes: Router.generateRoute,
class Router {
  static Map<String, GetRoute> generateRoute = {
    Routes.aboutUsView: GetRoute(page: AboutUsView()),
    Routes.accountView: GetRoute(page: AccountView()),
    Routes.entryView: GetRoute(page: EntryView()),
    // You no longer need to pass arguments, use
    // Get.arguments directly in the view, bloc, controller,
    // or anywhere. Get knows which view is open and gives
    // you the arguments anywhere.
  };
}

If you still don't want to migrate your application, you can use GetRouteBase rather GetRoute, but you won't have all the hotfixes that are made by us to make routes named work properly, especially in FlutterWeb

Jethro87 commented 4 years ago

Thanks for your quick response.

With the namedRoutes property, is one able to access route settings? For example, in this case:

      case Routes.entryView:
        final EntryViewArguments args = settings.arguments;
        return GetRoute(
          settings: settings,
          page: EntryView(
            entry: args.entry,
            index: args.index,
            isNew: args.isNew ?? false,
            isReviewing: args.isReviewing ?? false,
          ),
          fullscreenDialog: args.fullScreen ?? false,
        );

I'm setting fullScreenDialog based on the arguments passed. If I want to achieve the same result (choosing a full screen dialog for this route only in specific circumstances) with the new method, how would I do this?

jonataslaw commented 4 years ago

Well, the settings and fullScreenDialog properties are static with routesNamed. In that case, you must choose to use onGenerateRoute, or to create subroutes. Example:

class Router {
  static Map<String, GetRoute> generateRoute = {
    '/': GetRoute(page: First()),
    '/second': GetRoute(page: Second()),
    '/third': GetRoute(page: Third()),
    '/third/fullscreen': GetRoute(page: Third(), fullscreenDialog: true),
  };
}
Jethro87 commented 4 years ago

Gotcha. I'll consider the sub-route method. Thanks again.