Flutter Go Router no back button and nothing to pop
Asked Answered
D

3

12

I am using Go Router on my flutter project and I noticed that the back button is not presented anymore. Even when I specifically add it I get the following error:

======== Exception caught by gesture =============================================================== The following GoError was thrown while handling a gesture: There is nothing to pop When the exception was thrown, this was the stack: #0 GoRouterDelegate.pop (package:go_router/src/delegate.dart:120:5) #1 GoRouter.pop (package:go_router/src/router.dart:284:21) #2 RecordDetailState.build. (package:random_me/screens/record/detail.dart:70:36) #3 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21) #4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24) #5 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11) #6 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5) #7 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)

  Widget build(BuildContext context) {
    AppTranslations.init(context);
    return Scaffold(
      appBar: AppBar(
          title: Text(TRANSLATION.record_detail),
          leading: IconButton(
            onPressed: () {
              GoRouter.of(context).pop();
            },
            icon: Icon(Icons.arrow_back_ios),
            //replace with our own icon data.
          )),

Edit: If I call

GoRouter.of(context).push(CategoryDetail.routeName); 

instead of

GoRouter.of(context).go(CategoryDetail.routeName);

it works;

Discriminate answered 28/1, 2023 at 22:39 Comment(2)
The back button is not shown because Gorouter there is no page to go back to. This is also what the error message is telling you. Did you push any page? Can you show code of that?Incontestable
Ok I made it work If I call the push method instead of the go method it works GoRouter.of(context).push(CategoryDetail.routeName);Discriminate
D
37

Fixed: If I call

GoRouter.of(context).push(CategoryDetail.routeName); 

instead of

GoRouter.of(context).go(CategoryDetail.routeName);

it works;

Discriminate answered 28/1, 2023 at 23:46 Comment(1)
But the path is not showing in the address bar using this processBrentwood
G
20

It depends on how you managed your GoRoutes in your GoRouter configuration.

Whenever you use navigation, you have a "Navigation Stack" to manage.

Look at the two configurations below:

Configuration 1 without sub-route

/// The route configuration.
final GoRouter _router = GoRouter(
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return const HomeScreen();
      },
    ),
    GoRoute(
      path: '/details',
      builder: (BuildContext context, GoRouterState state) {
        return const DetailsScreen();
      },
    ),
  ],
);

Configuration 2 with sub-route

/// The route configuration.
final GoRouter _router = GoRouter(
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return const HomeScreen();
      },
      routes: <RouteBase>[
        GoRoute(
          path: 'details', // Note that you don't prefix the route with '/' since it will get it from its parent route
          builder: (BuildContext context, GoRouterState state) {
            return const DetailsScreen();
          },
        ),
      ],
    ),
  ],
);

First of all, you always start at the / route, which means that your navigation stack will contain the screen/page associated to the route /, so here HomeScreen.

Now, in Configuration 1, if you use context.go('/details'), since the routes / and /details are at the same level, your Navigation stack will update to replace HomeScreen with DetailsScreen. Therefore, if you use context.pop() in DetailsScreen, you will have an error because in the Navigation stack, there is indeed nothing to pop.

In Configuration 2, if you also use context.go('/details'), since the route /details is a sub-route of /, your Navigation stack will add the screen/page associated to the route /details on top of the screens/pages it already has, which means that it will contain [HomeScreen, DetailsScreen]. In this case, if you use context.pop() in DetailsScreen, you will pop DetailsScreen and go back to HomeScreen.

This is the behaviour regarding the go method. Now if you use the push method, it always adds the new screen/page on the of the Navigation stack, which means that you will always be able to use context.pop without worrying (unless you are at the / route where you won't have anything to pop).

Now it can seem better to use push always rather than go that seems to present a limitation, but the answer is: it depends on your use case, what you want to achieve.

One big limitation of the push method is that it doesn't work well with Deep Linking, whereas go method works great with it, but requires you to manage well how your configure your routes.

I invite you to read this great article that explains with examples the differences between using go and push methods.

Glee answered 19/2 at 10:48 Comment(1)
This is the right use of GoRouter. The accepted answer just solved the issue but destroyed the benefits of GoRouter.Brentwood
K
0

I have found another solution. For mobile back button, we have to use this

GoRouter.of(context).push(CategoryDetail.routeName);

But it will not change the url in web. for changing url we have to use this

GoRouter.of(context).go(CategoryDetail.routeName);

But it will again not show the back button on mobile.

for combine these both I have written an extension like this

import 'package:flutter/foundation.dart';

extension GoRouteExtension on BuildContext {
  goPush<T>(String route) =>
      kIsWeb ? GoRouter.of(this).go(route) : GoRouter.of(this).push(route);
}

Just copy this code and store this is in another separate file and all this like this

context.goPush(CategoryDetail.routeName);

It will show back button in mobile and also show the url while on flutter web. :)

Kinney answered 12/5 at 4:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.