Reputation: 189
I am trying to navigate to a screen from a future method. However I get an error saying undefined name context. I tried navigating from Widget build but the parameter is created within this method and I need it for navigating. I've been stuck on this for a very long time. Any help will be really appreciated.
Future<void> addBookingConversation(Booking booking) async {
Conversation conversation = Conversation();
await conversation.addConversationToFirestore(booking.posting.host); //additional method working fine
String text = "Hi, my name is ${AppConstants.currentUser.firstName}";
await conversation.addMessageToFirestore(text); //additional method working fine
//this is where i should navigate to the conversation page and facing the error here
Navigator.push(
context, //error here context undefined
MaterialPageRoute(builder:
(context) => ConversationPage(conversation: conversation,),
),
);
}
class ConversationPage extends StatefulWidget {
final Conversation conversation;
static final String routeName = '/conversationPageRoute';
ConversationPage({this.conversation, Key key}) : super(key: key);
@override
_ConversationPageState createState() => _ConversationPageState();
}
class _ConversationPageState extends State<ConversationPage> {
Conversation _conversation;
// additional code of wiget build
}
Upvotes: 2
Views: 3167
Reputation: 109
This method help you to navigate the route without FutureBuilder. see the code
onPressed: () async {
// then await the future You want to complete and then use `.then()`
//method to implement the code that you want to implement when the future is completed
await //call your future widget //
.then((result) {
print('future completed');
// Navigate here
// For errors use onError to show or check the errors.
}).onError((error, stackTrace) {
print(error);
});
}
Upvotes: 1
Reputation: 24970
Wrap your Navigator
inside :
WidgetsBinding.instance.addPostFrameCallback((_){
// 👈 Your Navigation here
});
Your Code:
Future<void> addBookingConversation(Booking booking) async {
...
WidgetsBinding.instance.addPostFrameCallback((_){
Navigator.push( //👈 add your navigation here
context, //error here context undefined
MaterialPageRoute(builder:
(context) => ConversationPage(conversation: conversation,),
),
);
...
}
Upvotes: 3
Reputation: 1215
If you want to call the navigator method anywhere in the app.
class NavigationService {
final GlobalKey<NavigatorState> globalKey = GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(Route Route) {
return globalKey.currentState.push(Route);
}
}
and in main.dart.
navigatorKey: NavigationService().globalKey,
and then anywhere within the app. Just use this
Future<void> addBookingConversation(Booking booking) async {
Conversation conversation = Conversation();
await conversation.addConversationToFirestore(booking.posting.host);
//additional method working fine
String text = "Hi, my name is ${AppConstants.currentUser.firstName}";
await conversation.addMessageToFirestore(text); //additional method working
fine
//this is where i should navigate to the conversation page and facing the
error here
NavigationService().navigateTo(
MaterialPageRoute(builder:
(context) => ConversationPage(conversation: conversation,),
),);
}
Upvotes: 1
Reputation: 77304
I don't know where your function resides, so this is some general advice:
If you cannot access a variable in your method you have two options: pass it in as a parameter from the caller. Or return the result to the caller so they can do the part where the variable is needed themselves.
What does that mean for your scenario: either you need the context
as an additional parameter in your method, or you need to return Future<Conversation>
from your method and handle the navigation where it's called.
Personally, I'd favor the second option, since your business logic of starting a conversation and your in-app navigation are two different concerns that should not be mixed in one method.
Upvotes: 1