I am new to Fluter and trying to tackle the navigation part using Bloc.
I would like to add the possibility to log out from any place in the application.
Details:
I am working on the Notes application (just for learning), and have wrapped MaterialApp with BlocProvider, so I can access AuthBloc from any place. MaterialApp 'home' widget is HomePage, which returns BlocConsumer, thus it can return a state depending on the event. So, if the user has logged in - I emit AuthStateLoggedIn and return a ViewNotePage. From the ViewNotePage (by clicking on a concrete Note) I go to NotePage, using MaterialPageRoute. And if I emit AuthEventLogOut (by press on the LogOut button) from the NotesListPage - nothing happens, until I invoke Navigator.of(context).popUntil(ModalRoute.withName('/')). Here is the code
void main() {
runApp(const MyApp());
}
// App
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider<AuthBloc>(
create: (context) => AuthBloc(FirebaseAuthProvider()),
child: MaterialApp(
title: 'Notes',
theme: Colors.blue,
home: const HomePage(),
routes: {
viewNotePage: (context) => const ViewNotePage(),
}
),
);
}
}
// HomePage
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
context
.read<AuthBloc>()
.add(const AuthEventInitialize());
return BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state.isLoading) {
// loading is handled here
}
},
builder: (context, state) {
if (state is AuthStateLoggedOut) {
return const LoginView();
} else if (state is AuthStateRegistering) {
return const RegisterView();
} else if (state is AuthStateNeedsVerification) {
return const VerifyEmailView();
} else if (state is AuthStateLoggedIn) {
return const NotesPage();
} else if (state is AuthStateForgotPassword) {
return const ForgotPasswordView();
}
return const Scaffold(body: CircularProgressIndicator());
},
);
}
}
// NotesPage
To shorten the code, basically, I do here:
await Navigator.of(context).pushNamed(viewNotePage, arguments: someArgs);
// ViewNotePage
context.read<AuthBloc>().add(const AuthEventLogOut());
Navigator.of(context).popUntil(ModalRoute.withName('/')); // without popUntil - I stay on the ViewNotePage
So from what I understand, when I use MaterialPageRoute - it creates a new tree under the MaterialApp and now it can not access BlocConsumer.
Can someone please point out, what is the correct way to handle this case? Is it a good idea to mix Bloc + Navigator features?
you can listen for the logout event using bloc listener and then call the navigator function