Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

showDialog() and push() cause a crash if pop() was called on the previous window before the opening animation was completed #981

Open
KlGleb opened this issue Dec 19, 2024 · 2 comments
Labels
new New issue request attention

Comments

@KlGleb
Copy link

KlGleb commented Dec 19, 2024

Describe the bug
showDialog() and push() cause a crash if pop() was called on the previous window before the opening animation was completed

Environment

name: untitled2
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: '>=3.4.3 <4.0.0'
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.6
  flutter_modular: ^6.3.4

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0


flutter:
  uses-material-design: true

To Reproduce
You need to do a pushNamed to a screen, then do a pop() on that screen until the animation is complete, then immediately call showDialog() or push(). This results in the following error:

======== Exception caught by widgets library =======================================================
The following StateError was thrown building Builder:
Bad state: Future already completed

The relevant error-causing widget was: 
  MaterialApp MaterialApp:file:///Users/gleb.klimov/StudioProjects/untitled2/lib/main.dart:25:26
When the exception was thrown, this was the stack: 
#1      Route.didComplete (package:flutter/src/widgets/navigator.dart:425:19)
#2      _RouteEntry.handleComplete (package:flutter/src/widgets/navigator.dart:3083:11)
#3      NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:4294:17)
#4      NavigatorState._updatePages (package:flutter/src/widgets/navigator.dart:4198:5)

This is because Navigator:didComplete is called 3 times after these actions, and the third time calling _popCompleter.complete() results in an error because it was already called the first time:

I/flutter ( 8768): Navigator:didComplete,  _popCompleter is called with null, settings: /second, isCompleted: false
I/flutter ( 8768): Navigator:didComplete,  _popCompleter is called with null, settings: null, isCompleted: false
I/flutter ( 8768): Navigator:didComplete,  _popCompleter is called with null, settings: /second, isCompleted: true

Code for reproducing:

import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';

void main() => runApp(const MyApp());

class AppModule extends Module {
  static const route = "/";

  @override
  void routes(RouteManager r) {
    r.redirect('/', to: '/first');
    r.child('/first', child: (context) => const FirstPage());
    r.child('/second', child: (context) => const SecondPage());
    r.child('/third', child: (context) => const ThirdPage());
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ModularApp(
      module: AppModule(),
      child: MaterialApp.router(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        routerConfig: Modular.routerConfig,
      ),
    );
  }
}

class FirstPage extends StatelessWidget {
  const FirstPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('First page')),
      body: Column(
        children: [
          const Center(child: Text('This is the first page')),
          OutlinedButton(onPressed: () => _testCase1(context), child: const Text('Navigate to the second page and show a dialog')),
          OutlinedButton(onPressed: () => _testCase3(context), child: const Text('Navigate to the second page and then to the third using push()')),
        ],
      ),
    );
  }

  void _testCase1(BuildContext context) {
    Modular.to.pushNamed('/second').then((value) {
      showDialog(context: context, builder: (context) => _getAlertDialog());
    });
  }

  void _testCase3(BuildContext context) {
    Modular.to.pushNamed('/second').then((value) {
      Modular.to.push(MaterialPageRoute(builder: (context) => const ThirdPage()));
    });
  }

  Widget _getAlertDialog() {
    return AlertDialog(
      title: const Text('You most likely won\'t see this dialog.'),
      actions: [
        TextButton(
          onPressed: () => Modular.to.pop(),
          child: const Text('Close'),
        )
      ],
    );
  }
}

class SecondPage extends StatefulWidget {
  const SecondPage({super.key});

  @override
  State<SecondPage> createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  void initState() {
    // do pop() before finishing the animation
    Future.delayed(const Duration(milliseconds: 80)).then((value) => Modular.to.pop());
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: const Text('Second page')));
  }
}

class ThirdPage extends StatelessWidget {
  const ThirdPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Third page')),
      body: const Center(
        child: Text('This is the third page'),
      ),
    );
  }
}

Screenshots

@KlGleb KlGleb added the new New issue request attention label Dec 19, 2024
@KlGleb
Copy link
Author

KlGleb commented Jan 20, 2025

Good afternoon!

I'd like to check with Contributors: does anyone understand what the problem is and how difficult it is to fix? As a result of this bug, we have no way to upgrade to the new version of modular (the old version has a workaround). Maybe someone could suggest a rough plan to fix the problem so that I can countertribute with less time-consuming code study?

@KlGleb
Copy link
Author

KlGleb commented Feb 27, 2025

Hi @jacobaraujo7 @edugemini @steniooliv , do you have any insights on this issue? Any information would be greatly appreciated. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new New issue request attention
Projects
None yet
Development

No branches or pull requests

1 participant