Here's how my project is build:
I have a router.dart file where the routing is managed
class MainRouter {
GoRouter router = GoRouter {
//...
}
}
I pass this GoRouter object into my MaterialApp.router-Widget:
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: MainRouter.router
//..
)
}
I have the BuildContext as an attribute at my AppEvent.
class AppEvent extends Equatable {
final BuildContext context;
const AppEvent(this.context);
@override
List<Object> get props => [context];
}
Now, I have an asynchronous callback function in my AppBloc where i need to delete something from the database first and then navigate to the home screen.
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
event.context.go("/home");
}
The problem is, I get following lint issue in my project saying: "Don't use 'BuildContext's across async gaps."
I know, according to this question that i can just check with event.context.mounted
to be safe the BuildContext is mounted, but i still have that lint issue.
I tried to access the MainRouter.router
directly and call MainRouter.router.go("/home")
and that worked, but would that violate any architectural rules either of the GoRouter or the Bloc-Architecture?
Thanks for your insights!
You could use a BlocConsumer
to listen for specific BLoC states, and define a state that would indicate you should go to that route.
class AppPopState extends AppState {
const AppPopState()
}
An then in your BLoC return that state:
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
emit(const AppPopState());
}
An listen to that state in your widget:
Widget build(context) {
return BlocConsumer(
listenWhen: (_, state) => state is AppPopState,
listener: (ctx, statte) {
context.go("/home");
},
...
Defined a global key for your GoRouter, and use it to navigate from your BLoC.
/// Root navigator key.
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
/// Navigation router.
final GoRouter kRouter = new GoRouter(
navigatorKey: rootNavigatorKey,
...
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
rootNavigatorKey.currentContext!.go("/home");
}