Skip to content

[go_router] moving namedLocation() from state to context breaks the use of named routes in the top-level redirect  #121506

@csells

Description

@csells

Steps to Reproduce

  1. add a top-level redirect method to a GoRouter instance
  2. call state.namedLocation('foo') and it works (assuming there's a route named 'foo'); however, the compiler complains that it's deprecated
  3. call context.namedLocation('foo') and it fails @ runtime because the context in this case is the same as the context holding the GoRouter and the GoRouter search begins at the next level higher in the widget tree

Logs

When attempting to call context.namedLocation('foo') in a top-level redirect, the runtime error is as follows:

Exception has occurred.
_AssertionError ('package:go_router/src/router.dart': Failed assertion: line 300 pos 12: 'inherited != null': No GoRouter found in context)

The top of flutter doctor -v looks like this:

[✓] Flutter (Channel stable, 3.7.5, on macOS 13.2.1 22D68 darwin-arm64, locale en-US)
    • Flutter version 3.7.5 on channel stable at /Users/csells/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision c07f788888 (4 days ago), 2023-02-22 17:52:33 -0600
    • Engine revision 0f359063c4
    • Dart version 2.19.2
    • DevTools version 2.20.1

I'm using go_router: ^6.2.0 in my pubspec.yaml.

Expected Behavior

I expect to be able to create named locations in a top-level redirect so I don't have to hardcode path names (i.e. the whole reason to use named locations). For example, the latest go_router named_routes example has dropped the use of top-level redirection from the original example which supported the use of named locations just fine, e.g.

   // redirect to the login page if the user is not logged in
    redirect: (state) {
      // if the user is not logged in, they need to login
      final loggedIn = loginInfo.loggedIn;
      final loginloc = state.namedLocation('login');
      final loggingIn = state.subloc == loginloc;

      // bundle the location the user is coming from into a query parameter
      final homeloc = state.namedLocation('home');
      final fromloc = state.subloc == homeloc ? '' : state.subloc;
      if (!loggedIn) {
        return loggingIn
            ? null
            : state.namedLocation(
                'login',
                queryParams: {if (fromloc.isNotEmpty) 'from': fromloc},
              );
      }

      // if the user is logged in, send them where they were going before (or
      // home if they weren't going anywhere)
      if (loggingIn) return state.queryParams['from'] ?? homeloc;

      // no need to redirect at all
      return null;
    },

By moving namedLocation from state to context, half the reason for named locations has been completely removed from go_router. Can this behavior be restored, please? Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: regressionIt was better in the past than it is nowp: go_routerThe go_router package

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions