Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get 5.0.0 Nested Navigation duplicate routes #3111

Open
egortabula opened this issue May 26, 2024 · 5 comments
Open

Get 5.0.0 Nested Navigation duplicate routes #3111

egortabula opened this issue May 26, 2024 · 5 comments
Assignees

Comments

@egortabula
Copy link

ATTENTION: DO NOT USE THIS FIELD TO ASK SUPPORT QUESTIONS. USE THE PLATFORM CHANNELS FOR THIS. THIS SPACE IS DEDICATED ONLY FOR BUGS DESCRIPTION.
Fill in the template. Issues that do not respect the model will be closed.

Describe the bug
Hello! In my app I use Nested Navigation, like described in nav 2 example. My application has a path home which contains 2 sub paths, orders and profile. The orders page also has an internal page with a description of the order. This is implemented using Nested navigation. When I'm on the order description screen, I try to open the settings page on top of the stack, which is on the same level as home. The settings page opens on top, but I noticed that in the DevTools inspector the settings page is duplicated twice. Why does this happen, and how to get rid of the double?

Reproduction code
NOTE: THIS IS MANDATORY, IF YOUR ISSUE DOES NOT CONTAIN IT, IT WILL BE CLOSED PRELIMINARY)

Full code https://github.com/egortabula/get_nested_navigation_test

My Routes

part of 'app_pages.dart';
// DO NOT EDIT. This is code generated via package:get_cli/get_cli.dart

abstract class Routes {
  Routes._();
  static const HOME = _Paths.HOME;
  static const PROFILE = HOME + _Paths.PROFILE;
  static const ORDERS = HOME + _Paths.ORDERS;
  static String orderDetails(String orderID) => '$ORDERS/$orderID';
  static const SETTINGS = _Paths.SETTINGS;

}

abstract class _Paths {
  _Paths._();
  static const HOME = '/home';
  static const PROFILE = '/profile';
  static const ORDERS = '/orders';
  static const ORDER_DETAILS = '/:orderId';
  static const SETTINGS = '/settings';
}

Pages

part 'app_routes.dart';

class AppPages {
  AppPages._();

  static const INITIAL = Routes.HOME;

  static final routes = [
    GetPage(
      name: '/',
      page: () => const RootView(),
      preventDuplicates: true,
      participatesInRootNavigator: true,
      children: [
        GetPage(
          name: _Paths.HOME,
          page: () => const HomeView(),
          binding: HomeBinding(),
          preventDuplicates: true,
          children: [
            GetPage(
              name: _Paths.PROFILE,
              page: () => const ProfileView(),
              binding: ProfileBinding(),
            ),
            GetPage(
              name: _Paths.ORDERS,
              page: () => const OrdersView(),
              binding: OrdersBinding(),
              participatesInRootNavigator: false,
              children: [
                GetPage(
                  name: _Paths.ORDER_DETAILS,
                  page: () => const OrderDetailsView(),
                  binding: OrderDetailsBinding(),
                ),
              ],
            ),
          ],
        ),
        GetPage(
          name: _Paths.SETTINGS,
          page: () => const SettingsView(),
          binding: SettingsBinding(),
          participatesInRootNavigator: true,
          preventDuplicates: true,
        ),
      ],
    ),
  ];
}

Home View with Nested Navigation

class HomeView extends GetView<HomeController> {
  const HomeView({super.key});
  @override
  Widget build(BuildContext context) {
    return GetRouterOutlet.builder(
      route: Routes.HOME,
      builder: (context) {
        return Scaffold(
          body: GetRouterOutlet(
            initialRoute: Routes.ORDERS,
            anchorRoute: Routes.HOME,
          ),
          bottomNavigationBar: IndexedRouteBuilder(
            builder: (context, routes, index) {
              final delegate = context.delegate;
              return NavigationBar(
                selectedIndex: index,
                onDestinationSelected: (value) =>
                    delegate.toNamed(routes[value]),
                destinations: const [
                  NavigationDestination(
                    icon: Icon(Icons.gif_box),
                    label: 'Заказы',
                  ),
                  NavigationDestination(
                    icon: Icon(Icons.person),
                    label: 'Профиль',
                  ),
                ],
              );
            },
            routes: const [Routes.ORDERS, Routes.PROFILE],
          ),
        );
      },
    );
  }
}

Orders View

class OrdersView extends GetView<OrdersController> {
  const OrdersView({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: List.generate(
          25,
          (int index) => ListTile(
            onTap: () => Get.toNamed(Routes.orderDetails('${index + 1000}')),
            title: Text('Заказ ${index + 1000}'),
          ),
        ),
      ),
    );
  }
}

Order Details View

class OrderDetailsView extends GetView<OrderDetailsController> {
  const OrderDetailsView({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Order ${Get.parameters['orderId'] ?? ''}'),
        centerTitle: true,
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => Get.toNamed(Routes.SETTINGS),
          child: const Text('settings'),
        ),
      ),
    );
  }
}

To Reproduce
Steps to reproduce the behavior:

  1. Open any order
  2. Click settings button
  3. Open dev tools in web browser
    4, Settings View is duplicated twice

Expected behavior
It seems to me that pages should not be duplicated. I checked the same example in GoRouter, there are no duplicate pages. But maybe I don't understand something?

Screenshots
Screenshot 2024-05-26 at 17 17 10
Screenshot 2024-05-26 at 17 18 44

Flutter Version:
5.22.1

Getx Version:
6.0.0 release-candidate-6

Describe on which device you found the bug:
IOS Simulator.15 Pro

Minimal reproduce code
Full code https://github.com/egortabula/get_nested_navigation_test

@hightman
Copy link

I have been studying GetX's Nav2 for some time.
You should use GetRouterOutlet.pickPages or filterPages to customize which GetPages should be placed in the current navigation stack.

@hightman
Copy link

However, in your example, you only need to remove the participatesInRootNavigator option from the settings page.

@egortabula
Copy link
Author

However, in your example, you only need to remove the participatesInRootNavigator option from the settings page.

Hello! I tried to remove participatesInRootNavigator param. it worked, but in this case, I can't return to previous page:(

@hightman
Copy link

However, in your example, you only need to remove the participatesInRootNavigator option from the settings page.

Hello! I tried to remove participatesInRootNavigator param. it worked, but in this case, I can't return to previous page:(

Are you referring to the default AppBar not showing the back button?
You can refer to the code below to specify the leading property.

AppBar(
        leading: RouterListener(builder: (context) {
          final delegate = context.delegate;
          if (delegate.canBack) {
            return BackButton(
              onPressed: () {
                delegate.back();
              },
            );
          } else {
            return const DrawerButton();
          }
        }),
        title: RouterListener(builder: (context) {
          final title = context.location;
          return Text(title);
        }),
        centerTitle: true,
      )

@hightman
Copy link

Now you can refer to my sample code, which has implemented page state preservation.

https://github.com/hightman/getx5-example_nav2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants