Milad-Akarie / auto_route_library

Flutter route generator
MIT License
1.59k stars 405 forks source link

customRouteBuilder's completion result type has broken in the 8.0.3 version #1913

Open SergeShkurko opened 7 months ago

SergeShkurko commented 7 months ago

Now, return types don't work with customRouteBuilder correctly

Because of the last commit c2953feab41f6931ee25943df971386fb9462cd3. Type annotation removed from the function

/// Signature for custom router builder used by
/// [CustomRouteType]
-typedef CustomRouteBuilder = Route<T> Function<T>(
+typedef CustomRouteBuilder<T> = Route<T> Function(
  BuildContext context,
  Widget child,
  AutoRoutePage<T> page,
);

Then any reusable customRouteBuilder implementation will return Route with a dynamic type. We won't return any route with passed by router type. We need to handle generics inside the function. Like earlier

Screenshot 2024-04-03 at 03 27 02

More earlier versions work pretty

Milad-Akarie commented 7 months ago

@SergeShkurko try specifiying the type when returning your custom Route e.gDialogRoute<String>(....)

LocLt-Mobile commented 7 months ago

I have same issue.

Skogsfrae commented 7 months ago

@Milad-Akarie I'm running into the same problem mainly because I have a custom class that extends the CustomRoute class to avoid boilerplate code, so I can't explicitly pass the return type.

I have different CustomRoute classes with different animations that combined in the navigation stack perform different forward/back animations such as iOS modal animations styles.

class MyRoute extends CustomRoute {
  MyRoute({
    required super.page,
    ...
    super.opaque,
  }) : super(customRouteBuilder: <T>(BuildContext context,
    Widget child,
    AutoRoutePage<T> page,
  ) => MyRoutePage<T>(
              builder: (context) => child,
              settings: page,
            ));
}

I solved with this workaround that forces me to specify the return type in the navigation tree declaration too:

class MyRoute<R> extends CustomRoute {
  MyRoute({
    required super.page,
    ...
    super.opaque,
  }) : super(customRouteBuilder: (BuildContext context,
    Widget child,
    AutoRoutePage<T> page,
  ) => MyRoutePage<R>(
              builder: (context) => child,
              settings: page,
            ));
}
Mik77o commented 6 months ago

We encounter the same issue for 8.0.3.

class DialogAutoRoute extends CustomRoute {
  DialogAutoRoute({
    required super.page,
    super.barrierDismissible,
    super.path,
  }) : super(
          opaque: false,
          transitionsBuilder: TransitionsBuilders.fadeIn,
          durationInMilliseconds: dialogAutoRouteDefaultDuration,
          reverseDurationInMilliseconds: dialogAutoRouteDefaultDuration,
          customRouteBuilder: <T>(context, child, routePage) => DialogRoute(
            context: context,
            builder: (_) => child,
            barrierDismissible: barrierDismissible,
            settings: routePage,
          ),
        );
}
vpohrebniako commented 6 months ago

Any plans on fixing this issue?

Mixron469 commented 4 months ago

Still same issues for me when I upgrade auto_route to Ver. 8, with my both custom bottomSheet route and dialog route.

akadatsky commented 4 months ago

Any updates on this issue?

Milad-Akarie commented 4 months ago

Make sure your return type is exclusively provided in both annotation and route implementation.

@RoutePage<String>() /// this page returns a string value
class MyPage extends StatelessWidget {}
CustomRoute(
      page: MyRoute.page,
      customRouteBuilder: (context, child, page) {
        return MyCustomRoute<String>( // provide the same return type
          builder: (context) => child,
          settings: page,
        );
      },
    ),
Mixron469 commented 3 months ago

Make sure your return type is exclusively provided in both annotation and route implementation.

@RoutePage<String>() /// this page returns a string value
class MyPage extends StatelessWidget {}
CustomRoute(
      page: MyRoute.page,
      customRouteBuilder: (context, child, page) {
        return MyCustomRoute<String>( // provide the same return type
          builder: (context) => child,
          settings: page,
        );
      },
    ),

@Milad-Akarie

My custom route screen is

@RoutePage<bool>(name: 'ProductInfoBottomSheetRoute')
class ProductInfoBottomSheet extends ConsumerWidget {
  const ProductInfoBottomSheet({
    super.key,
    @pathParam required this.productId,
  });

  final String productId;

my route is

        AppCustomBottomSheetRoute<bool>(
          path: 'warehouse/myorder/detail/:productId',
          page: ProductInfoBottomSheetRoute.page,
        ),

and my AppCustomBottomSheetRoute is

class AppCustomBottomSheetRoute<T> extends CustomRoute {
  AppCustomBottomSheetRoute({
    required String super.path,
    required super.page,
    super.barrierDismissible = false,
    Color? barrierColor,
    bool isScrollControlled = true,
    super.children,
  }) : super(
          opaque: false,
          barrierColor: barrierColor ?? Colors.black.withOpacity(0.48),
          fullscreenDialog: false,
          transitionsBuilder: TransitionsBuilders.noTransition,
          customRouteBuilder: <T>(BuildContext context, Widget child, AutoRoutePage<T> page) {
            return ModalBottomSheetRoute<T>(
              settings: page,
              builder: (context) => child,
              isScrollControlled: isScrollControlled,
            );
          },
        );
}

when I try to push like

await context.router.pushNamed<bool>('warehouse/myorder/detail/${item.id}').then((bool? value) {
            if (value ?? false) {
              Future.delayed(const Duration(milliseconds: 150), () {
                context.router.pushNamed('warehouse/edit-product/${item.id}');
              });
            }
          });

it will throw Screenshot 2567-07-18 at 15 11 28

Note: this implementation work fine before upgrade to auto_route 8, after that upgrade, it throw me an error and I cannot work with custom route anymore

Milad-Akarie commented 3 months ago

Did you run the generator after setting @RoutePage

Mixron469 commented 3 months ago

Did you run the generator after setting @RoutePage

@Milad-Akarie Yes, my router.gr.dart file is

    ProductInfoBottomSheetRoute.name: (routeData) {
      final pathParams = routeData.inheritedPathParams;
      final args = routeData.argsAs<ProductInfoBottomSheetRouteArgs>(
          orElse: () => ProductInfoBottomSheetRouteArgs(
              productId: pathParams.getString('productId')));
      return AutoRoutePage<bool>(
        routeData: routeData,
        child: ProductInfoBottomSheet(
          key: args.key,
          productId: args.productId,
        ),
      );
    },

/// generated route for
/// [ProductInfoBottomSheet]
class ProductInfoBottomSheetRoute
    extends PageRouteInfo<ProductInfoBottomSheetRouteArgs> {
  ProductInfoBottomSheetRoute({
    Key? key,
    required String productId,
    List<PageRouteInfo>? children,
  }) : super(
          ProductInfoBottomSheetRoute.name,
          args: ProductInfoBottomSheetRouteArgs(
            key: key,
            productId: productId,
          ),
          rawPathParams: {'productId': productId},
          initialChildren: children,
        );

  static const String name = 'ProductInfoBottomSheetRoute';

  static const PageInfo<ProductInfoBottomSheetRouteArgs> page =
      PageInfo<ProductInfoBottomSheetRouteArgs>(name);
}

class ProductInfoBottomSheetRouteArgs {
  const ProductInfoBottomSheetRouteArgs({
    this.key,
    required this.productId,
  });

  final Key? key;

  final String productId;

  @override
  String toString() {
    return 'ProductInfoBottomSheetRouteArgs{key: $key, productId: $productId}';
  }
}

with auto_route: ^8.3.0 auto_route_generator: ^8.0.0

you can see #1942 is a fix of this custom route error that now I using it instead of official in pub version, you should review it.

outring commented 3 months ago

Same thing here. I'm specifying a custom route type via type in routes:

@AutoRouterConfig()
class AppRouter extends $AppRouter {
  @override
  late final List<AutoRoute> routes = [
    AutoRoute(page: SomePage.page, type: CustomRouteType(customRouteBuilder: <T>(BuildContext context, Widget child, AutoRoutePage<T> page) {
      return MyPageRoute<T>(settings: page, builder: (context) => child);
    })),
  ];
}

The error is:

TypeError: Instance of 'MyPageRoute<dynamic>': type 'MyPageRoute<dynamic>' is not a subtype of type 'Route<BookkeepingTaskSessionResult>'

Which is quite logical, since CustomRouteType is not generic the type paramter for customRouteBuilder can't be inferred AOT and dynamic is being used. The PR https://github.com/Milad-Akarie/auto_route_library/pull/1942 looks legit

Mixron469 commented 3 months ago

Did it was resolved in latest 9.3.0?