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

RouterOutlet routes persist even when parent route is popped #960

Open
zssnyder opened this issue Jun 4, 2024 · 3 comments · May be fixed by #961
Open

RouterOutlet routes persist even when parent route is popped #960

zssnyder opened this issue Jun 4, 2024 · 3 comments · May be fixed by #961
Labels
new New issue request attention

Comments

@zssnyder
Copy link

zssnyder commented Jun 4, 2024

Describe the bug
Calling Modular.to.pop() or Navigator.of(context).pop() in a widget wrapping a RouterOutlet doesn't dispose of the RouterOutlet's widget tree. This appears to be specific to RouterOutlets displaying a dynamic route. Each time the dynamic route is pushed and popped, the RouterOutlet builds an additional widget tree.

Environment
Add your flutter doctor -v

[✓] Flutter (Channel stable, 3.19.5, on macOS 14.2.1 23C71 darwin-arm64, locale en-US)
    • Flutter version 3.19.5 on channel stable at /Users/zssnyder/Projects/Libraries/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 300451adae (10 weeks ago), 2024-03-27 21:54:07 -0500
    • Engine revision e76c956498
    • Dart version 3.3.3
    • DevTools version 2.31.1

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.


[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Users/zssnyder/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.89.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.90.0

[✓] Network resources
    • All expected network resources are available.

To Reproduce

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

void main() {
  runApp(ModularApp(module: AppModule(), child: const MainApp()));
}

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

  @override
  Widget build(BuildContext context) {
    Modular.setInitialRoute('/home');

    return MaterialApp.router(
      title: "RouterOutlet Test",
      routerConfig: Modular.routerConfig,
    );
  }
}

class AppModule extends Module {
  @override
  void routes(RouteManager r) {
    r.child('/', child: (context) => const HomePage(), children: [
      ChildRoute('/home', child: (context) => const ChildPage('0')),
    ]);
    r.module('/child', module: ChildModule());
  }
}

class ChildModule extends Module {
  @override
  void routes(RouteManager r) {
    r.child('/', child: (context) => const ParentPage(), children: [
      ChildRoute('/:id', child: (context) => ChildPage(r.args.params['id'])),
    ]);
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int id = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: const RouterOutlet(),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.arrow_forward_rounded),
        onPressed: () {
          Modular.to.pushNamed('/child/$id');

          setState(() {
            id++;
          });
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back_rounded),
          onPressed: () => Modular.to.pop(),
        ),
      ),
      body: const RouterOutlet(),
    );
  }
}

class ChildPage extends StatelessWidget {
  const ChildPage(this.id, {super.key});

  final String id;

  @override
  Widget build(BuildContext context) {
    print(id);

    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Text(id),
      ),
    );
  }
}

Expected behavior
Each time the floating action button is pressed to navigate to the Child Module's route, the "id" passed into the route should be printed once.

Screenshots
Running on iOS Simulator (17.4)
https://github.com/Flutterando/modular/assets/19160564/f9253516-f72f-45be-a92e-d47eb332cb85

Output:

flutter: 0
flutter: 1
flutter: 1
flutter: 2
flutter: 2
flutter: 2
flutter: 3
flutter: 3
flutter: 3
flutter: 3
@zssnyder zssnyder added the new New issue request attention label Jun 4, 2024
@zssnyder
Copy link
Author

zssnyder commented Jun 4, 2024

pubspec.yaml

name: modular_bug
description: "A new Flutter project."
publish_to: 'none'
version: 0.1.0

environment:
  sdk: '>=3.3.3 <4.0.0'

dependencies:
  flutter:
    sdk: flutter

  flutter_modular: ^6.3.4

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:
  uses-material-design: true

@zssnyder zssnyder linked a pull request Jun 4, 2024 that will close this issue
7 tasks
@luccacondratiuk
Copy link

luccacondratiuk commented Jul 16, 2024

@zssnyder I was having the same problem, tested your solution and it worked, thanks!!
But the master branch, was breaking I had to change to the modular_lite branch

dependency_overrides:
  flutter_modular:
    git:
      url: https://github.com/zssnyder/flutter_modular.git
      ref: modular_lite
      path: flutter_modular
  modular_core:
    git:
      url: https://github.com/zssnyder/flutter_modular.git
      ref: modular_lite
      path: modular_core

@aissat
Copy link

aissat commented Sep 22, 2024

same issue
flutter_modular: ^6.3.4

Flutter 3.26.0-0.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision ee624bc4fd (12 days ago) • 2024-09-10 17:41:06 -0500
Engine • revision 059e4e6d8f
Tools • Dart 3.6.0 (build 3.6.0-216.1.beta) • DevTools 2.39.0
class DemoHome extends StatelessWidget {
  const DemoHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () => Modular.to.pushNamed(Routes.s1),
            child: const Text('Scrren1'),
          ),
          ElevatedButton(
            onPressed: () => Modular.to.pushNamed(Routes.s2),
            child: const Text('Scrren2'),
          ),
        ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: const Color(0xFF162866),
        foregroundColor: Colors.white,
        centerTitle: true,
        title: const Text('Demo Page'),
        leading: const BackButton(color: Colors.white),
      ),
      body: const Center(
        child: RouterOutlet(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      color: Colors.blue,
      child: const Text('Scrren1'),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      color: Colors.green,
      child: const Text('Scrren2'),
    );
  }
}

/// DemoModule
class DemoModule extends Module {
  .....
  void routes(RouteManager r) {
    
    r.child('demoHome', child: (_) => const DemoHome(), children: []);
    r.child(
      'demoPage',
      child: (_) => const DemoPage(),
      children: [
        ChildRoute(
          'scrren1',
          child: (_) => const Scrren1(),
          children: [],
        ),
        ChildRoute(
          'scrren2',
          child: (_) => const Scrren2(),
          children: [],
        ),
      ],
    );
  }
}

/// AppModule

class AppModule extends Module {
  .....
  @override
  void routes(RouteManager r) {
    
    r.module(
      '/demo',
      module: DemoModule(),
      transition: TransitionType.rightToLeft,
      guards: [],
    );
  }
}

////
  static String demo = '/demo/demoHome';
  static String s1 = '/demo/demoPage/scrren1';
  static String s2 = '/demo/demoPage/scrren12';

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

Successfully merging a pull request may close this issue.

3 participants