Nin Yu
Nin Yu

Reputation: 21

I am trying to run two await and a navigator.push in an async function, and i got this error in flutter

Error: [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. E/flutter ( 6342): At this point the state of the widget's element tree is no longer stable. E/flutter ( 6342): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method. E/flutter ( 6342): #0 Element._debugCheckStateIsActiveForAncestorLookup. (package:flutter/src/widgets/framework.dart:3864:9) E/flutter ( 6342): #1 Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3878:6) E/flutter ( 6342): #2 Element.findAncestorStateOfType (package:flutter/src/widgets/framework.dart:3926:12) E/flutter ( 6342): #3 Navigator.of (package:flutter/src/widgets/navigator.dart:2706:40) E/flutter ( 6342): #4 Navigator.pop (package:flutter/src/widgets/navigator.dart:2592:15) E/flutter ( 6342): #5 NotificationDialog.checkAvailabilityOfRide (package:drivers_app/Notifications/notificationDialog.dart:240:20) E/flutter ( 6342):

Snippet of my code:

 void checkAvailabilityOfRide(context) async {
    
      var rideRequestId = await rideRequestRef.once();
           ...
      var dataSnapShot2 =  await newRequestsRef.child(rideRequestId.value).once();
           ...
     Navigator.push(context, MaterialPageRoute(builder: (context)=> 
      NewRideScreen(rideDetails: rideDetails)));
         ...
   }

Updated Code:

 Widget build(BuildContext context) {
 return Dialog(
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
  backgroundColor: Colors.transparent,
  elevation: 1.0,
  child: Container(
    margin: EdgeInsets.all(5.0),
    width: double.infinity,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(5.0),
    ),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        SizedBox(height: 30.0),
        Image.asset("images/taxi.png", width: 120.0,),
        SizedBox(height: 18.0,),
        Text("New Ride Request", style: TextStyle(fontFamily: "Brand-Bold", fontSize: 18.0,),),
        SizedBox(height: 30.0),
        Padding(
          padding: EdgeInsets.all(18.0),
          child: Column(
            children: [

              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Image.asset("images/pickicon.png", height: 16.0, width: 16.0,),
                  SizedBox(width: 20.0,),
                  Expanded(
                    child: Container(child: Text(rideDetails.pickup_address, style: TextStyle(fontSize: 18.0),)),
                  ),
                ],
              ),
              SizedBox(height: 15.0),

              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Image.asset("images/desticon.png", height: 16.0, width: 16.0,),
                  SizedBox(width: 20.0,),
                  Expanded(
                    child: Container(child: Text(rideDetails.dropOff_address, style: TextStyle(fontSize: 18.0),)),
                  )
                ],
              ),
              SizedBox(height: 15.0),

            ],
          ),
        ),

        SizedBox(height: 20.0),
        Divider(height: 2.0,color: Colors.black, thickness: 2.0,),
        SizedBox(height: 8.0),

        Padding(
          padding: EdgeInsets.all(20.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [

              FlatButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18.0),
                    side: BorderSide(color: Colors.red)),
                color: Colors.white,
                textColor: Colors.red,
                padding: EdgeInsets.all(8.0),
                onPressed: ()
                {
                  assetsAudioPlayer.stop();
                  Navigator.pop(context);
                },
                child: Text(
                  "Cancel".toUpperCase(),
                  style: TextStyle(
                    fontSize: 14.0,
                  ),
                ),
              ),

              SizedBox(width: 25.0),

              RaisedButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18.0),
                    side: BorderSide(color: Colors.green)),
                onPressed: ()
                {
                  assetsAudioPlayer.stop();
                  checkAvailabilityOfRide0(context);
                  checkAvailabilityOfRide(context);
                },

                color: Colors.green,
                textColor: Colors.white,
                child: Text("Accept".toUpperCase(),
                    style: TextStyle(fontSize: 14)),
              ),

            ],
          ),
        ),

        SizedBox(height: 10.0),
      ],
    ),
  ),
);

}

Future<void> checkAvailabilityOfRide(context) async {
   var rideRequestId = await rideRequestRef.once();
   Navigator.push(context);
   String theRideId = "";
   var dataSnapShot2 =  await newRequestsRef.child( rideRequestId.value).once();
   /*... process...*/

   if(theRideId == rideDetails.ride_request_id && r2canShare) {
   rideRequestRef.set("accepted");
   AssistantMethods.disableHomeTabLiveLocationUpdates();
   Navigator.push(context, MaterialPageRoute(builder: (context) => 
   NewRideScreen(rideDetails: rideDetails)));
 }
   else if(theRideId == 'cancelled') {
   displayToastMessage("Ride has been Cancelled.", context);
   }
   else if(theRideId == 'cancelled') {
   displayToastMessage("Ride has been time out.", context);
   }
   else if(r2canShare == false) {
   assetsAudioPlayer.stop();
   displayToastMessage("Rider 2 cannot shared ride, out of range.", context);
   }
   else {
   displayToastMessage("Ride not exists.", context);
   }

}

altered code:

  void checkAvailabilityOfRide(context)async{
    var dataSnapShot2 =  await newRequestsRef.child( (await 
      rideRequestRef.once()).value).once();
    Navigator.pop(context);
    String theRideId = "";
    /*... process...*/

Upvotes: 1

Views: 1594

Answers (2)

Patrick O&#39;Hara
Patrick O&#39;Hara

Reputation: 2229

As the poster found (see comments on question), the error is caused by having an async await execute between the Navigator.pop and Navigator.push. I guess the await gives Flutter time to destroy the current screen before the push, which causes the exception on the push.

Note that Flutter provides various ways to pop and push at the same time, which avoid the chance of having intervening code: pushReplacement and pushReplacementNamed replace the current screen with a new one, and popAndPushNamed does the same with different animation.

Upvotes: 1

Ankit Tale
Ankit Tale

Reputation: 2004

@Nin Yu, Past some days I got the same error I tried to fix using @Patrick answer, but that didn't work too sometimes. When I closely debug it I found I was calling method containing Navigator multiple times. So sometimes I got context and I pass safely to the next screen and some it throws an error. I would suggest debug method and check whether it occurence.

Upvotes: 0

Related Questions