Describe the bug
Octopus router automatically deduplicates routes by name when replacing the top route. If a route with the same name already exists in the stack, calling replace() (upsertLast or something like that) removes the existing instance instead of creating a new one.
To Reproduce
Steps to reproduce the behavior:
- Navigate to home
- Push gallery
- Push picture
- Call replace('home')
Observe the result
Expected behavior
The stack should result in: [home, gallery, home]
The new home route should replace picture without affecting the earlier instance of home.
Actual behavior
The resulting stack is: [gallery, home]
Octopus removes the earlier instance of home, which is unexpected.
Flutter Doctor
[✓] Flutter (Channel stable, 3.32.4, on macOS 15.5 24F74 darwin-arm64, locale en-KZ)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.101.1)
[✓] Connected device (3 available)
! Error: Browsing on the local area network for Aidar’s iPhone 15 Pro...
[✓] Network resources
• No issues found!
Additional context
I have potential ideas, but they all seem hardcoded. I would like to ask you, as a package author, if there is a competent solution to this kind of cases? Thanks!
Code:
import 'package:flutter/material.dart';
import 'package:octopus/octopus.dart';
enum Routes with OctopusRoute {
home('home'),
gallery('gallery'),
picture('picture');
const Routes(this.name);
@override
final String name;
@override
Widget builder(BuildContext context, OctopusState state, OctopusNode node) =>
switch (this) {
Routes.home => const HomeScreen(),
Routes.gallery => const GalleryScreen(),
Routes.picture => const PictureScreen(),
};
}
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final router = Octopus(routes: Routes.values, defaultRoute: Routes.home);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router.config,
builder: (context, child) => OctopusTools(
octopus: router,
child: child ?? const SizedBox.shrink(),
),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: Column(
children: [
Text(
'Current stack: ${context.octopus.state.children.map((c) => c.name).toList()}',
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => context.octopus.push(Routes.gallery),
child: const Text('Push to Gallery'),
),
],
),
),
);
}
}
class GalleryScreen extends StatelessWidget {
const GalleryScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Gallery')),
body: Center(
child: Column(
children: [
Text(
'Current stack: ${context.octopus.state.children.map((c) => c.name).toList()}',
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => context.octopus.push(Routes.picture),
child: const Text('Push to Picture'),
),
],
),
),
);
}
}
class PictureScreen extends StatelessWidget {
const PictureScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Picture')),
body: Center(
child: Column(
children: [
Text(
'Current stack: ${context.octopus.state.children.map((c) => c.name).toList()}',
),
const SizedBox(height: 20),
Text('After replace i want stack: [home, gallery, home]'),
ElevatedButton(
onPressed: () {
context.octopus.upsertLast(Routes.home);
},
child: const Text('Replace Picture with Home'),
),
],
),
),
);
}
}
Describe the bug
Octopus router automatically deduplicates routes by name when replacing the top route. If a route with the same name already exists in the stack, calling
replace()(upsertLast or something like that) removes the existing instance instead of creating a new one.To Reproduce
Steps to reproduce the behavior:
Observe the result
Expected behavior
The stack should result in:
[home, gallery, home]The new home route should replace picture without affecting the earlier instance of home.
Actual behavior
The resulting stack is:
[gallery, home]Octopus removes the earlier instance of home, which is unexpected.
Flutter Doctor
[✓] Flutter (Channel stable, 3.32.4, on macOS 15.5 24F74 darwin-arm64, locale en-KZ)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.101.1)
[✓] Connected device (3 available)
! Error: Browsing on the local area network for Aidar’s iPhone 15 Pro...
[✓] Network resources
• No issues found!
Additional context
I have potential ideas, but they all seem hardcoded. I would like to ask you, as a package author, if there is a competent solution to this kind of cases? Thanks!
Code: