Using Beamer router with flutter, the url changes but the navigation doesn't happen

Issue

I am trying to use beamer for navigation in my flutter web app. It seems to be partially working, but I am encountering some issues.

The first page is the sign in page, and when I sign in, after the authentication, the nagvigator is supposed to navigate to the home page. When I sign in, and authentication is successful, I can see the url change in the browser, however, the page stays the same. The page changes if I refresh the page from the browser.

Here is related code:

class _MyAppState extends State<MyApp> {

  final routerDelegate = BeamerDelegate(
      locationBuilder: RoutesLocationBuilder(
        routes: {
          '/': (context, state, data){
            return const BeamPage(
                title: 'Welcome to Space Shuttle Parking',
                child: SplashScreenDesktop()
            );
          },
          '/sign_in': (context, state, data){
            return const BeamPage(
                title: 'Sign in to your account',
                child: SigninPage()
            );
          },
          '/sign_up': (context, state, data){
            return const BeamPage(
                title: 'Create a new account',
                child: SigninPage()
            );
          },
          '/main/:page': (context, state, data){
            final page = state.pathParameters['page']!;
            return BeamPage(
              title: page.capitalizeFirst,
              child: LandingPage(page: page, extra: '',)
            );
          },
          '/main/:page/:extra': (context, state, data){
            final page = state.pathParameters['page']!;
            final extra = state.pathParameters['extra']!;
            return BeamPage(
              title: page.capitalizeFirst,
              child: LandingPage(page: page, extra: extra,)
            );
          }
        }
      )
  );

  @override
  void initState() {
    //SpaceShuttleRouter.setupRouter();
    super.initState();
  }
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: BeamerParser(),
      routerDelegate: routerDelegate,
      title: 'Space Shuttle Parking - Booking Manager',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        fontFamily: 'Assistant'
      ),
    );
  }
}

This is where I am signing in and navigating:

AuthController().signInWithEmailAndPassword(email, password, () {
  Fluttertoast.showToast(
    msg: 'Please wait'
  );
  Beamer.of(context).beamToNamed('/main/home');

},

Solution

You seem to be lacking page keys, without them Navigator doesn’t replace the current beam page.

Example for your case:

'/sign_up': (context, state, data){
  return const BeamPage(
    key: ValueKey("sign_up"),
    title: 'Create a new account',
    child: SigninPage()
  );
},

https://pub.dev/packages/beamer#page-keys

Page Keys

When we beam somewhere, we are putting a new list of pages into
Navigator.pages. Now the Navigator has to decide on the transition
between the old list of pages and the new list of pages.

In order to know which pages changed and which pages stayed the same,
Navigator looks at the pages’ keys. If the keys of 2 pages that
are compared are equal (important here: null == null), Navigator
treats them as the same page and does not rebuild nor replace that
page.

One should always set a BeamPage.key (most likely a
ValueKey).
If keys are not set, after beaming somewhere via e.g.
Beamer.of(context).beamToNamed('/somewhere'), no change will happen
in the UI. The new BeamPage doesn’t build since Navigator thinks
it is the same as the already displayed one.

Answered By – Bungeefan

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *