-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
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