Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.2.0

- Adds `void replace()` and `replaceNamed` to `GoRouterDelegate`, `GoRouter` and `GoRouterHelper`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add an empty line between two versions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops sorry for that, I added that in 8ec9776


## 4.1.0

- Adds `bool canPop()` to `GoRouterDelegate`, `GoRouter` and `GoRouterHelper`.
Expand Down
20 changes: 20 additions & 0 deletions packages/go_router/lib/go_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@ extension GoRouterHelper on BuildContext {
extra: extra,
);

/// Replaces the current location with the given one w/ optional query
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Replaces the current location with the given one w/ optional query
/// Replaces the top-most page of page stack with the given URL location w/ optional query

/// parameters, e.g. `/family/f2/person/p1?color=blue
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also mention go/push use

See also:

 * [go], which ....
 * [push], which ...

void replace(String location, {Object? extra}) =>
GoRouter.of(this).replace(location, extra: extra);

/// Replaces the current location with the named route w/ optional parameters,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Replaces the current location with the named route w/ optional parameters,
/// Replaces the top-most page of page stack with the named route w/ optional parameters,

/// e.g. `name='person', params={'fid': 'f2', 'pid': 'p1'}`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also use the See also to mention goNamed and pushNamed

void replaceNamed(
String name, {
Map<String, String> params = const <String, String>{},
Map<String, String> queryParams = const <String, String>{},
Object? extra,
}) =>
GoRouter.of(this).replaceNamed(
name,
params: params,
queryParams: queryParams,
extra: extra,
);

/// Returns `true` if there is more than 1 page on the stack.
bool canPop() => GoRouter.of(this).canPop();

Expand Down
26 changes: 26 additions & 0 deletions packages/go_router/lib/src/go_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,32 @@ class GoRouter extends ChangeNotifier with NavigatorObserver {
extra: extra,
);

/// Replaces the current location with the given one w/ optional query
/// parameters, e.g. `/family/f2/person/p1?color=blue
void replace(String location, {Object? extra}) {
routeInformationParser
.parseRouteInformation(
DebugGoRouteInformation(location: location, state: extra),
)
.then<void>((List<GoRouteMatch> matches) {
routerDelegate.replace(matches.last);
});
}

/// Replaces the current location with the named route w/ optional parameters,
/// e.g. `name='person', params={'fid': 'f2', 'pid': 'p1'}`
void replaceNamed(
String name, {
Map<String, String> params = const <String, String>{},
Map<String, String> queryParams = const <String, String>{},
Object? extra,
}) {
replace(
namedLocation(name, params: params, queryParams: queryParams),
extra: extra,
);
}

/// Returns `true` if there is more than 1 page on the stack.
bool canPop() => routerDelegate.canPop();

Expand Down
6 changes: 6 additions & 0 deletions packages/go_router/lib/src/go_router_delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ class GoRouterDelegate extends RouterDelegate<List<GoRouteMatch>>
notifyListeners();
}

/// Replaces the current location with the given one.
void replace(GoRouteMatch match) {
_matches.last = match;
notifyListeners();
}

/// Returns `true` if there is more than 1 page on the stack.
bool canPop() {
return _matches.length > 1;
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: 4.1.0
version: 4.2.0
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
46 changes: 46 additions & 0 deletions packages/go_router/test/go_router_delegate_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,52 @@ void main() {
);
});

group('replace', () {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding a test for replaceNamed too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test for replaceNamed in 44e35ef Tell me what you think about it

testWidgets(
'It should replace the last match with the given one',
(WidgetTester tester) async {
final GoRouter goRouter = GoRouter(
initialLocation: '/',
routes: <GoRoute>[
GoRoute(path: '/', builder: (_, __) => const SizedBox()),
GoRoute(path: '/page-0', builder: (_, __) => const SizedBox()),
GoRoute(path: '/page-1', builder: (_, __) => const SizedBox()),
],
);
await tester.pumpWidget(
MaterialApp.router(
routeInformationProvider: goRouter.routeInformationProvider,
routeInformationParser: goRouter.routeInformationParser,
routerDelegate: goRouter.routerDelegate,
),
);

goRouter.push('/page-0');

goRouter.routerDelegate.addListener(expectAsync0(() {}));
final GoRouteMatch first = goRouter.routerDelegate.matches.first;
final GoRouteMatch last = goRouter.routerDelegate.matches.last;
goRouter.replace('/page-1');
expect(goRouter.routerDelegate.matches.length, 2);
expect(
goRouter.routerDelegate.matches.first,
first,
reason: 'The first match should still be in the list of matches',
);
expect(
goRouter.routerDelegate.matches.last,
isNot(last),
reason: 'The last match should have been removed',
);
expect(
goRouter.routerDelegate.matches.last.fullpath,
'/page-1',
reason: 'The new location should have been pushed',
);
},
);
});

testWidgets('dispose unsubscribes from refreshListenable',
(WidgetTester tester) async {
final FakeRefreshListenable refreshListenable = FakeRefreshListenable();
Expand Down