Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 17.3.1

- Fixes `popRoute()` crashing with `Bad state: No element` when
`currentConfiguration` is empty (e.g. during app startup before
the first route resolves).

## 17.3.0

- Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.
Expand Down
10 changes: 7 additions & 3 deletions packages/go_router/lib/src/delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList> with ChangeNotifie
return true; // Return true if maybePop handled the pop
}
}

if (currentConfiguration.isEmpty) {
return false;
}
// Fallback to onExit if maybePop did not handle the pop
final GoRoute lastRoute = currentConfiguration.last.route;
if (lastRoute.onExit != null && navigatorKey.currentContext != null) {
Expand All @@ -79,7 +81,7 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList> with ChangeNotifie
if (navigatorKey.currentState?.canPop() ?? false) {
return true;
}
if (currentConfiguration.matches.isEmpty) {
if (currentConfiguration.isEmpty) {
return false;
}
RouteMatchBase walker = currentConfiguration.matches.last;
Expand Down Expand Up @@ -115,7 +117,9 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList> with ChangeNotifie
// Set state directly without canPop check
states.add(navigatorKey.currentState!);
}

if (currentConfiguration.isEmpty) {
return states.reversed;
}
RouteMatchBase walker = currentConfiguration.matches.last;
while (walker is ShellRouteMatch) {
final NavigatorState potentialCandidate = walker.navigatorKey.currentState!;
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: go_router
description: A declarative router for Flutter based on Navigation 2 supporting
deep linking, data-driven routes and more
version: 17.3.0
version: 17.3.1
repository: https://github.com/flutter/packages/tree/main/packages/go_router
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22

Expand Down
17 changes: 17 additions & 0 deletions packages/go_router/test/delegate_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,23 @@ void main() {
});
});

testWidgets('popRoute does not throw Bad state when currentConfiguration is empty', (
WidgetTester tester,
) async {
final GoRouter goRouter = GoRouter(
initialLocation: '/',
routes: <GoRoute>[GoRoute(path: '/', builder: (_, _) => const DummyStatefulWidget())],
);
addTearDown(goRouter.dispose);
await tester.pumpWidget(MaterialApp.router(routerConfig: goRouter));

// Simulate empty configuration (e.g. startup window before first route resolves)
goRouter.routerDelegate.currentConfiguration = RouteMatchList.empty;

// Should return false without throwing "Bad state: No element"
expect(await goRouter.routerDelegate.popRoute(), isFalse);
});

group('push', () {
testWidgets('It should return different pageKey when push is called', (
WidgetTester tester,
Expand Down