szavs
szavs

Reputation: 189

Navigation inside future method flutter

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

Answers (4)

Hari .S
Hari .S

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

krishnaacharyaa
krishnaacharyaa

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

DIVYANSHU SAHU
DIVYANSHU SAHU

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

nvoigt
nvoigt

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

Related Questions