Peter Irving
Peter Irving

Reputation: 405

Go Router (Flutter)- push the exact same route and refresh that route

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

Answers (6)

Ledjon
Ledjon

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

Dila
Dila

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

Ahmed Nishaal
Ahmed Nishaal

Reputation: 96

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

context.pushReplacement(url);

Upvotes: 1

Ritesh Singh
Ritesh Singh

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

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

Upvotes: 3

Pablo Insua
Pablo Insua

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

Related Questions