nivisi / GetNavigatorIssue

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Get Navigator Issue

This is a reproduction of the GetNavigator bug, the issue is opened here.

The problem

It would be nice to have an opportunity to use the GetNavigator for nested navigation. So it will be easier to extract the named navigation data and even initialize pages.

Although, when the GetNavigator is placed somewhere in the widget tree, like here, the following bug occurs:

=[GETX] Route "/notes" not found

════════ Exception caught by widgets library ═══════════════════════════════════
Null check operator used on a null value
The relevant error-causing widget was
GetNavigator-[LabeledGlobalKey<NavigatorState>#13608]
lib/pages/home_page.dart:36
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<NavigatorState>#13608] was used by 2 widgets
    GetNavigator-[LabeledGlobalKey<NavigatorState>#13608]
    Navigator-[LabeledGlobalKey<NavigatorState>#13608]
        dirty
        dependencies: [UnmanagedRestorationScope, _EffectiveTickerMode]
        state: NavigatorState#6bd96(lifecycle state: initialized)
════════════════════════════════════════════════════════════════════════════════

The expected behaviour

Is to actually use the GetNavigator and be able to navigate via nested navigators.

  1. Create the navigator:
  GetNavigator(
      key: Get.nestedKey(AppRoutes.todosKey),
      initialRoute: AppRoutes.todos,
      getPages: [
        GetPage(
          name: AppRoutes.todos,
          page: () {
            return TodosPage();
          },
        ),
        GetPage(
          name: '${AppRoutes.todos}/:id',
          binding: TodoBinding(),
          page: () {
            return TodoPage();
          },
        ),
      ],
    ),
  1. Navigate:
Get.toNamed('${AppRoutes.todos}/todoId');
  1. Extract the data in the binding and put the controller:
class TodoBinding extends Bindings {
  @override
  void dependencies() {
    final text = Get.parameters['id'];
    Get.put(TodoController(todo));
  }
}
  1. Use it:
class TodoController extends GetxController {
  final String id;
  Todo todo;

  TodoController(this.id);

  @override
  void onInit() {
    super.onInit();
    final todos = Get.find<TodosController>().todos;
    todo = todos.firstWhere(
      (item) => item.id == id,
    );
  }
}

class TodoPage extends GetView<TodoController> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('TODO: ${controller.todo.title}'),
        BackButton(),
      ],
    );
  }
}

This behaviour works well for the regular navigation. The Test button in the upper-right corner of the app bar reproduces it.

The workaround

... is to use the simple Navigator and handle the upcoming "URL" parameters by ourselves. The parsing code could be better for sure, but let's leave it as is for this example.

Navigator(
      key: Get.nestedKey(AppRoutes.todosKey),
      initialRoute: AppRoutes.todos,
      onGenerateRoute: (settings) {
        return GetPageRoute(
          settings: settings,
          page: () {
            if (settings.name == '/') {
              return Text('Initial');
            }
            if (settings.name == AppRoutes.todos) {
              return TodosPage();
            }
            final id = settings.name.replaceFirst(AppRoutes.todos + '/', '');
            Get.put(TodoController(id));

            return TodoPage();
          },
        );
      },
    ),

About


Languages

Language:Dart 94.1%Language:Swift 4.2%Language:Kotlin 1.4%Language:Objective-C 0.4%