Skip to content

Commit d1f5f87

Browse files
[go_router] Make replace use pop and push to generate a new pageKey (#2747)
* 🐛 Use pop and push in replace to generate a new pageKey * ✅ Test that replace creates a new page key * ⬆️ Increase the version number * ♻️ Move the asserts to the router deleguate * Wrap _debugAssertMatchListNotEmpty in an assert * Update packages/go_router/lib/src/delegate.dart Co-authored-by: John Ryan <[email protected]>
1 parent 77c9fea commit d1f5f87

File tree

5 files changed

+60
-14
lines changed

5 files changed

+60
-14
lines changed

packages/go_router/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 5.1.8
2+
3+
- Fixes a bug with `replace` where it was not generated a new `pageKey`.
4+
15
## 5.1.7
26

37
- Adds documentation using dartdoc topics

packages/go_router/lib/src/delegate.dart

+26-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
4545
final bool routerNeglect;
4646

4747
RouteMatchList _matchList = RouteMatchList.empty();
48+
49+
/// Stores the number of times each route route has been pushed.
50+
///
51+
/// This is used to generate a unique key for each route.
52+
///
53+
/// For example, it would could be equal to:
54+
/// ```dart
55+
/// {
56+
/// 'family': 1,
57+
/// 'family/:fid': 2,
58+
/// }
59+
/// ```
4860
final Map<String, int> _pushCounts = <String, int>{};
4961
final RouteConfiguration _configuration;
5062

@@ -136,9 +148,21 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
136148
return navigatorKey.currentState?.canPop() ?? false;
137149
}
138150

151+
void _debugAssertMatchListNotEmpty() {
152+
assert(
153+
_matchList.isNotEmpty,
154+
'You have popped the last page off of the stack,'
155+
' there are no pages left to show',
156+
);
157+
}
158+
139159
/// Pop the top page off the GoRouter's page stack.
140160
void pop() {
141161
_matchList.pop();
162+
assert(() {
163+
_debugAssertMatchListNotEmpty();
164+
return true;
165+
}());
142166
notifyListeners();
143167
}
144168

@@ -147,8 +171,8 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
147171
/// See also:
148172
/// * [push] which pushes the given location onto the page stack.
149173
void replace(RouteMatch match) {
150-
_matchList.matches.last = match;
151-
notifyListeners();
174+
_matchList.pop();
175+
push(match); // [push] will notify the listeners.
152176
}
153177

154178
/// For internal use; visible for testing only.

packages/go_router/lib/src/matching.dart

-11
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,10 @@ class RouteMatchList {
7474
void pop() {
7575
_matches.removeLast();
7676

77-
_debugAssertNotEmpty();
78-
7977
// Also pop ShellRoutes when there are no subsequent route matches
8078
while (_matches.isNotEmpty && _matches.last.route is ShellRoute) {
8179
_matches.removeLast();
8280
}
83-
84-
_debugAssertNotEmpty();
8581
}
8682

8783
/// An optional object provided by the app during navigation.
@@ -98,13 +94,6 @@ class RouteMatchList {
9894

9995
/// Returns the error that this match intends to display.
10096
Exception? get error => matches.first.error;
101-
102-
void _debugAssertNotEmpty() {
103-
assert(
104-
_matches.isNotEmpty,
105-
'You have popped the last page off of the stack,'
106-
' there are no pages left to show');
107-
}
10897
}
10998

11099
/// An error that occurred during matching.

packages/go_router/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: go_router
22
description: A declarative router for Flutter based on Navigation 2 supporting
33
deep linking, data-driven routes and more
4-
version: 5.1.7
4+
version: 5.1.8
55
repository: https://github.com/flutter/packages/tree/main/packages/go_router
66
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22
77

packages/go_router/test/delegate_test.dart

+29
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,35 @@ void main() {
154154
);
155155
},
156156
);
157+
testWidgets(
158+
'It should return different pageKey when replace is called',
159+
(WidgetTester tester) async {
160+
final GoRouter goRouter = await createGoRouter(tester);
161+
expect(goRouter.routerDelegate.matches.matches.length, 1);
162+
expect(
163+
goRouter.routerDelegate.matches.matches[0].pageKey,
164+
null,
165+
);
166+
167+
goRouter.push('/a');
168+
await tester.pumpAndSettle();
169+
170+
expect(goRouter.routerDelegate.matches.matches.length, 2);
171+
expect(
172+
goRouter.routerDelegate.matches.matches.last.pageKey,
173+
const Key('/a-p1'),
174+
);
175+
176+
goRouter.replace('/a');
177+
await tester.pumpAndSettle();
178+
179+
expect(goRouter.routerDelegate.matches.matches.length, 2);
180+
expect(
181+
goRouter.routerDelegate.matches.matches.last.pageKey,
182+
const Key('/a-p2'),
183+
);
184+
},
185+
);
157186
});
158187

159188
group('replaceNamed', () {

0 commit comments

Comments
 (0)