Reputation: 405
With GoRouter, Is there a way to push the exact same route with a different parameter and make the page reload? I am thinking of something like Navigator.pushReplacement
I am using context.go('/my_page/?param={someID}') to push to MyPage (a stateful widget)
The initial push to this route works fine and I load up the page for the particular ID
I am trying to push this same route again (replace the route and reload with different ID) using context.go('/my_page/?param={differentID}'). My breakpoints are hitting the return statement in my GoRoute pageBuilder, and I also hit a breakpoint in MyPage.build. I see the new ID passed into this widget when breakpointing in the build.
But the Page does not rebuild visually (or break in initState - side note, init state is used to load up a couple cubits with the passed in ID - could the page being a stateful widget be the problem?)
Maintain state on the Material Page is false. Also, pushing different routes works just fine.
Is this a stateful widget issue (meaning relocate all of my cubit init calls)? or is there a different way to push the same route?
EDIT _____________
This question was specific to rebuilding the same route, but the greater problem I was working on was to infinitely drill into the same page over and over again, while maintaining the navigation stack.
I was using a state manager to hold a list of routes and trigger the navigation by using context.go() to replace the current route completely.
is there a way to dynamically nest routes with context.push() while maintaining the entire nav stack?
Upvotes: 21
Views: 19442
Reputation: 123
Another way to do that is by passing in extra param current timestamp. This way you can avoid the caching of the page
context.go(yourUrlHere, extra: DateTime.now().millisecondsSinceEpoch)
Upvotes: 2
Reputation: 31
None of the solutions worked for me. I had a similar problem, I'm making a quiz app and wanted to have one code(bloc and view) for all the questionnaires. I have a QuizPage:
class QuizPage extends StatelessWidget {
const QuizPage({super.key, required this.id});
final String id;
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => QuizBloc(id: id)..add(GetQuizEvent(id: id)),
child: const QuizView(),
);
}
}
I use the id to change the questionnaire. On my start game I used
context.go('/game/1.1');
But on the end of the 1.1 questionnaire the go('/game/1.2') didnt refreshed the page so the bloc didnt made a request for the new questionnaire.
My solution was to use the UniqueKey()
suggested by @Pablo Insua and passed a unique key to the QuizPage on the router like this:
GoRoute(
path: '/game/:id',
builder: (context, GoRouterState state) =>
QuizPage(
key: UniqueKey(),
id: state.pathParameters['id'] ?? "",
),
),
I`m on go_router version ^14.0.2
Upvotes: 3
Reputation: 96
I used the following method, reading the docs strings for context.go method helped a lot
context.pushReplacement(url);
Upvotes: 1
Reputation: 1100
So this problem will only show up if the route is nested (shell routes) and you have pushed a new route using context.pushNamed('route-name')
or context.push('name')
.
You can simply await the child route to pop using the following code snippet.
onTap: () async {
final bool? result = await context.push<bool>('/page2');
if(result ?? false)...
// TODO: here can be the refresh logic
}
This is mentioned in go_router docs. This won't reinitiate the page. . If you want to reinitiate the page every time the page shows up. The answer will be using UniqueKey()
as suggested above. But this will cause issue with transition animation.
Upvotes: 0
Reputation: 81
I think context.replace
would accomplish what you are trying to do, since it should replace what is currently on the stack.
Upvotes: 3
Reputation: 1022
After some research, I have noticed that you can redirect to the same page by using pageKey: UniqueKey()
in the definition of the GoRoute().
Example code from my project:
GoRoute(
path: RoutePaths.serviceDetail.value,
name: RouteNames.serviceDetail.value,
pageBuilder: (context, state) {
return CustomTransitionPage<void>(
key: UniqueKey(),
child: const ServiceDetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
PageTransitions.subpageTransition(animation, child),
);
},
),
Upvotes: 21