21

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?

5
  • For clarification: Why is context.push() not fitting in your case? With .go you will replace the whole navigation stack so you can't "add" another route with it
    – jraufeisen
    Commented Aug 23, 2022 at 12:25
  • Honestly I probably did a whole unnecessary workaround. Please see my Edit above to explain the entire issue I was trying to solve Commented Aug 23, 2022 at 19:36
  • Your edit was very helpful, thanks. But I am really suprised about your obversations. When MyPage.build() is called, then this will lead to a visual update. Are you sure that ths is the problem? Do you want to show the code where you call context.go and the contents of MyPage.build?
    – jraufeisen
    Commented Aug 24, 2022 at 14:13
  • 3
    @PeterIrving: were you able to find a solution please ? I’m facing the same issue and both the answers below doesn’t seem to work. Any help would be much appreciated.
    – midNight
    Commented Nov 4, 2022 at 2:05
  • Did someone find a solution about this problem ? @PeterIrving
    – Madere
    Commented Jul 11, 2023 at 7:14

6 Answers 6

21

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),
        );
    },
),
4
  • 1
    This does push the same route again but just without any transition. So I don't think it's a solution. I am using go_router: ^3.1.1. Commented Nov 29, 2022 at 6:44
  • Maybe you should update the library to the latest version... 5.2.0 :D Commented Nov 29, 2022 at 16:04
  • Updated to 5.2.0 and it has the same behavior. It's just pushing the same route again but without any transition. You can verify it by pressing back after you try to push and then see if the same screen opens up or not. Commented Dec 2, 2022 at 8:59
  • 4
    Doesn't refresh the route 6.5 Commented Mar 29, 2023 at 8:42
3

I think context.replace would accomplish what you are trying to do, since it should replace what is currently on the stack.

3
  • 1
    What you want to say is to use GoRouter.of(getContext!).replace('page-route') Commented Sep 6, 2023 at 5:47
  • Worked for me. Nice! Commented Oct 10, 2023 at 21:57
  • 1
    @ShehzadAhmad context.replace() is an extension method which uses GoRouter.of(context).replace()
    – Dosenbiiir
    Commented Apr 16, 2024 at 10:35
3

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

2
  • 1
    What is the difference from Pablo's answer?
    – Kyle Venn
    Commented May 22, 2024 at 1:24
  • 1
    Now that you've pointed out the similarity between the answers, I've seen that in fact the only difference is that he used pageBuilder and I used builder. As others have commented, his answer didn't solve my problem, what it did was prevent my page from reloading, i.e. when I left context.go('/game/1.1'); and went to context.go('/game/1.2'); the page just didn't reload. Now I searched the difference between the two and found this.
    – Dila
    Commented May 23, 2024 at 14:39
2

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)
1

I used the following method, reading the docs strings for context.go method helped a lot

context.pushReplacement(url);
0

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.

1
  • Could you point where it's mentioned in the docs?
    – Tayan
    Commented May 8, 2024 at 9:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.