Displaying Loading Indicator with BlocListener Across Routes in Flutter Web with Initial Authentication

31 Views Asked by At

I am working on a Flutter Web application that utilizes flutter_bloc for state management and AzureAD for authentication. The authentication process is initiated right after runApp(MyApp()) in the main.dart, making it automatic and not requiring any manual login from the user. The relevant code snippet for the initial setup is as follows:

MultiBlocProvider(
  providers: [
    BlocProvider(
      create: (context) => AuthBloc(authRepository: authRepository)..add(AuthInitializationEvent()),
    ),
  ],
  // Child: MaterialApp and routes setup
)

Within the MaterialApp, I have defined several routes:

navigatorKey: globalNavigatorKey,
routes: {
  '/': (context) => RootScreen(),
  '/page1': (context) => Page1(),
  '/page2': (context) => Page2(),
},

In the RootScreen, I utilize a BlocListener to listen for authentication status changes:

BlocListener<AuthBloc, AuthState>(
  listener: (context, state) {
    if (state.status == AuthStatus.inProgress) {
      // Intention to show loading indicator
    } else if (state.status == AuthStatus.authenticated) {
      globalNavigatorKey.currentState?.pushNamedAndRemoveUntil(
        '/Page1',
        (route) => false,
      );
    }
  },
  // Child: BlocBuilder to rebuild UI based on state
)

I am facing a challenge with displaying a loading indicator (CircularProgressIndicator) across different routes, especially when the user refreshes the page (F5) while on a route other than the root ('/'). The loading indicator appears as intended when navigating through the app normally, but not when the page is refreshed or manual navigated to a non-root route.

How can I ensure that the loading indicator is consistently displayed across all routes during the initial authentication process, regardless of the current route or if the user refreshes the page? Additionally, how can I structure the BlocListener and BlocBuilder to handle this scenario effectively, considering the authentication process is automatic and happens initially?

Any guidance or insights on how to address this issue would be greatly appreciated. Thank you in advance!

1

There are 1 best solutions below

0
Chihiro On

Try modifying it as follows

final _navigatorKey = GlobalKey<NavigatorState>();
    
NavigatorState get _navigator => _navigatorKey.currentState!;

and

    child: MaterialApp(
      navigatorKey: _navigatorKey,

finally

_navigator .pushNamedAndRemoveUntil(
    '/Page1',
    (route) => false,
  );