Skip to content

[go_router] Root redirect has incomplete GoRouterState #106461

@harkairt

Description

@harkairt
Code for reproduction
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(const App());
}

class App extends StatefulWidget {
  const App({Key? key}) : super(key: key);

  @override
  State<App> createState() => _AppState();
}

class _AppState extends State<App> {
  late GoRouter router;

  @override
  void initState() {
    router = GoRouter(
      initialLocation: '/auth/login',
      debugLogDiagnostics: true,
      redirect: (state) {
        debugPrint('_ROOT_Should I redirect from: ${state.location}');
        debugPrint("_ROOT_name: ${state.name}");
        debugPrint("_ROOT_fullpath: ${state.fullpath}");
        debugPrint("_ROOT_path: ${state.path}");
        debugPrint("_ROOT_subloc: ${state.subloc}");
        debugPrint("_ROOT_queryParams: ${state.queryParams}");
        return null;
      },
      routes: [
        GoRoute(
          path: '/',
          name: "root",
          redirect: (state) => "/auth",
        ),
        GoRoute(
          path: '/auth',
          builder: (context, state) => const Page(title: '/auth'),
          name: "authRoot",
          routes: [
            GoRoute(
              path: 'login',
              name: "login",
              builder: (context, state) => const Page(title: '/auth/login'),
            ),
          ],
        ),
        GoRoute(
          path: '/contact',
          name: 'contact',
          redirect: (state) {
            debugPrint('Should I redirect from: ${state.location}');
            debugPrint("name: ${state.name}");
            debugPrint("fullpath: ${state.fullpath}");
            debugPrint("path: ${state.path}");
            debugPrint("subloc: ${state.subloc}");
            debugPrint("queryParams: ${state.queryParams}");
            return null;
          },
          builder: (context, state) {
            debugPrint('___ Building ${state.location}');
            debugPrint("___ name: ${state.name}");
            debugPrint("___ fullpath: ${state.fullpath}");
            debugPrint("___ path: ${state.path}");
            debugPrint("___ subloc: ${state.subloc}");
            debugPrint("___ queryParams: ${state.queryParams}");
            return const Page(title: '/contact');
          },
        ),
      ],
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: router.routerDelegate,
      routeInformationParser: router.routeInformationParser,
    );
  }
}

class Page extends StatelessWidget {
  const Page({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(title),
      ),
    );
  }
}

The app starts at /auth/login, if I change the URL to /contact?debug=param The following messages are written to the console:

_ROOT_Should I redirect from: /contact?debug=param
_ROOT_name: null
_ROOT_fullpath: null
_ROOT_path: null
_ROOT_subloc: /contact
_ROOT_queryParams: {debug: param}
Should I redirect from: /contact?debug=param
name: contact
fullpath: /contact
path: /contact
subloc: /contact
queryParams: {debug: param}
___ Building /contact?debug=param
___ name: contact
___ fullpath: /contact
___ path: /contact
___ subloc: /contact
___ queryParams: {debug: param}

First the root level GoRouterRedirect is invoked, then the GoRoute's GoRouterRedirect, and lastly the GoRoute's GoRouterWidgetBuilder.

Issue

The root level redirect is missing some values. name, path, fullpath are null.

I'd like to build some guard behaving abstraction on top of GoRouterRedirect, but since I cannot use the name I have to work with subloc, which ties my code to the GoRoute's path param, and I don't want various versions of my location URIs lying around willy-nilly in my code. 😅

Desired

GoRouter's GoRouterRedirect invocation should receive all information about the destination route, most importantly the name.

Reproducible with:

  • Flutter 2.10.1, 3.0.3
  • go_router 3.1.1, 4.0.0

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listfound in release: 3.0Found to occur in 3.0found in release: 3.1Found to occur in 3.1has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: go_routerThe go_router packagepackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions