Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: RouteAware triggers only didPush event

Hello i'm new to flutter and although i have already searched on this topic, it is unclear to me. So here is the code:

main.dart file

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await DotEnv().load('.env');
  final UserRepository userRepository = new UserRepository();
  runApp(BlocProvider(
    create: (context) => AuthenticationBloc(userRepository)..add(AppStarted()),
    child: App(
      userRepository: userRepository
    ),
  ));
}

profile_form.dart (is on another file and imports the routeObserver from main.dart)

class ProfileForm extends StatefulWidget {
  final UserRepository _userRepository;
  final User _user;

  ProfileForm(
      {Key key, @required UserRepository userRepository, @required User user})
      : assert(userRepository != null && user != null),
        _userRepository = userRepository,
        _user = user,
        super(key: key);
  State<ProfileForm> createState() => _ProfileFormState();
}

class _ProfileFormState extends State<ProfileForm> with RouteAware {

  UserRepository get _userRepository => widget._userRepository;
  User get _user => widget._user;

  

  @override
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() {
    routeObserver.subscribe(this, ModalRoute.of(context));
    super.didChangeDependencies();
  }

  @override
  void didPush() {
    print('didPush FirstPage');
  }

  @override
  void didPopNext() {
    print('didPopNext FirstPage');
  }

  @override
  void didPop() {
    print('didPop FirstPage');
  }

  @override
  void didPushNext() {
    print('didPushNext FirstPage');
  }

  @override
  void dispose() {
    print("dis");
    routeObserver.unsubscribe(this);
    super.dispose();
  }
}

This form is entered through the Navigator.pushReplacementNamed(context, '/profile'); Although the trigger of didPush() event fires when i go back to another page (again from Nanigator or back button) and waiting for the didPop() event to fire it does not. What do i miss here? My main problem is that i want to save changes when the user exits the profile screen but before entering the init of another screen.

like image 911
kostasandre Avatar asked Oct 20 '25 04:10

kostasandre


1 Answers

I had a similar problem so if this can help anyone, here's what caused it. The problem was that the RouteObserver that the RouteAware was subscribing to, was a different one from the one that was used by MaterialApp.

So the RouteObserver in MaterialApp was checking didPush & didPop events, but didn't have any listeners. The reason that you still get a didPush event, is because the observer always sends a didPush when you subscribe.

The root cause in our case, was that we used a Provider to provide the RouteObserver to the RouteAware widget, but everytime the MaterialApp was rebuilt, it got a new RouteObserver different from the one created by the provider.

Check if the RouteObserver you are subscribing to is the same one that's being used by MaterialApp, using the hashCode property!

like image 105
RienK Avatar answered Oct 21 '25 22:10

RienK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!