13

Hello everyone this is a question I have been asking myself for quite sometime. I have also seen some answers to it, but it didn't solve my problem, some similar questions that I found are: Flutter showDialog with navigator key rather than passing context or Navigator operation requested with a context that does not include a Navigator

What I am trying to achieve is to show popup dialog anywhere in my app (so in any page of my app) from the same piece of code (so it's all concentrated). The issue is that from that piece of code I do not have access to the BuildContext, this is because I'm showing this popups based on events that do not come from a user action (like button tap), instead they could be Firestore listeners, or errors that occur deep into my code (so I can show an error message to the user), since I'm so deep into the code, usually I don't have access to the BuildContext.

In the similar questions, I found something that looks like a solution. These solutions use a GlobalKey for the navigator so can access it from anywhere, there are some different options on how to access it anywhere in the app, in my case I opted for a Singleton (my "Repository") where I store this globalKey. Then when the event is fired I use the globalKey to get the context and show a Dialog, but it throws this error:

Navigator operation requested with a context that does not include a Navigator. The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget. 

@Hemanth Raj mentions that your root Widget needs to be a MaterialApp, I do have a MaterialApp as my root.

Here is an approximation of the structure of the app I have:

void main() async { // Here I create the navigatorKey GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); // I then init my Singleton with the navigatorKey await repository.init(navigatorKey: navigatorKey); // Then I pass the navigatorKey down to my App runApp(MyApp(debugMode: debugMode, navigatorKey: navigatorKey)); } class MyApp extends StatefulWidget { final navigatorKey; const MyApp({Key key, this.navigatorKey}) : super(key: key); @override MyAppState createState() => MyAppState(); } class MyAppState extends State<MyApp> with WidgetsBindingObserver { @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: widget.navigatorKey, title: 'My app', home: SplashPage(), theme: _buildMyTheme(), ); } } 

Then in my Repository I have a listener for firestore events. These can fire anytime after I am in my home-screen. The idea is wherever I find myself within the app, if the event is fired the popup should appear.

class Repository { GlobalKey<NavigatorState> get navigatorKey => _navigatorKey; GlobalKey<NavigatorState> _navigatorKey; void init({GlobalKey<NavigatorState> navigatorKey}) { _navigatorKey = navigatorKey; } void _listenToEvents() { streamWithEvents.listen((event) { showDialog( context: navigatorKey.currentContext, builder: (_) => CustomMessageDialog(message: event.message), ); }); } } 
1

1 Answer 1

11

Use navigatorKey.currentState.overlay.context for showDialog's context.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for your answer! I'll try this one out, and get back to you. If this works I will put this answer as the correct answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.