[bug]: router generator create multiples screen arguments with same name
Describe the bug
I'm trying to create 2 nested routes:
- /shop/giftguide
- /explore/giftguide
Both points to the same giftguide screen.
Running dart run build_runner build --delete-conflicting-outputs it generates NestedGiftGuideScreenArguments 2 times in my .router.dart class causing me some headache.
Is there something wrong I'm doing?
To reproduce
router.dart
@StackedApp(
routes: [
MaterialRoute(
//path: '/home',
page: HomeScreen,
// initial: true,
),
MaterialRoute(
path: '/shop',
page: ShopNavigationStackScreen,
children: [
MaterialRoute(path: 'shophome', page: ShopScreen),
MaterialRoute(path: 'giftguide', page: GiftGuideScreen),
],
),
MaterialRoute(
path: '/explore',
page: ExploreNavigationStackScreen,
children: [
MaterialRoute(path: 'giftguide', page: GiftGuideScreen),
],
)
],
)
class App {
// This class has no purpose besides housing the annotation that generates the required functionality
}
shopNavigationStackScreen.dart
class ShopNavigationStackScreen extends StatelessWidget {
const ShopNavigationStackScreen({Key? key}) : super(key: key);
static var router = ExtendedNavigator(
router: ShopNavigationStackScreenRouter(),
navigatorKey: StackedService.nestedNavigationKey(
ScalaRouteConfig.shopNavigationId,
),
initialRoute: ShopNavigationStackScreenRoutes.shopScreen,
);
@override
Widget build(BuildContext context) {
return router;
}
}
exploreNavigationStackScreen.dart
class ExploreNavigationStackScreen extends StatelessWidget {
const ExploreNavigationStackScreen ({Key? key}) : super(key: key);
static var router = ExtendedNavigator(
router: ExploreNavigationStackScreenRouter(),
navigatorKey: StackedService.nestedNavigationKey(
ScalaRouteConfig.shopNavigationId,
),
initialRoute: ExploreNavigationStackScreenRoutes.shopScreen,
);
@override
Widget build(BuildContext context) {
return router;
}
}
generated router.router.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// StackedNavigatorGenerator
// **************************************************************************
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:flutter/material.dart' as _i5;
import 'package:flutter/material.dart';
import 'package:routing_test/screen/explore_navigation_stack_screen.dart'
as _i4;
import 'package:routing_test/screen/gift_guide_screen.dart' as _i7;
import 'package:routing_test/screen/home_screen.dart' as _i2;
import 'package:routing_test/screen/shop_navigation_stack_screen.dart' as _i3;
import 'package:routing_test/screen/shop_screen.dart' as _i6;
import 'package:stacked/stacked.dart' as _i1;
import 'package:stacked_services/stacked_services.dart' as _i8;
class Routes {
static const homeScreen = '/home-screen';
static const shopNavigationStackScreen = '/shop-navigation-stack-screen';
static const exploreNavigationStackScreen =
'/explore-navigation-stack-screen';
static const all = <String>{
homeScreen,
shopNavigationStackScreen,
exploreNavigationStackScreen,
};
}
class StackedRouter extends _i1.RouterBase {
final _routes = <_i1.RouteDef>[
_i1.RouteDef(
Routes.homeScreen,
page: _i2.HomeScreen,
),
_i1.RouteDef(
Routes.shopNavigationStackScreen,
page: _i3.ShopNavigationStackScreen,
),
_i1.RouteDef(
Routes.exploreNavigationStackScreen,
page: _i4.ExploreNavigationStackScreen,
),
];
final _pagesMap = <Type, _i1.StackedRouteFactory>{
_i2.HomeScreen: (data) {
return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i2.HomeScreen(),
settings: data,
);
},
_i3.ShopNavigationStackScreen: (data) {
return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i3.ShopNavigationStackScreen(),
settings: data,
);
},
_i4.ExploreNavigationStackScreen: (data) {
return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i4.ExploreNavigationStackScreen(),
settings: data,
);
},
};
@override
List<_i1.RouteDef> get routes => _routes;
@override
Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap;
}
class ShopNavigationStackScreenRoutes {
static const shopScreen = 'shophome';
static const giftGuideScreen = 'gift-guide-screen';
static const all = <String>{
shopScreen,
giftGuideScreen,
};
}
class ShopNavigationStackScreenRouter extends _i1.RouterBase {
final _routes = <_i1.RouteDef>[
_i1.RouteDef(
ShopNavigationStackScreenRoutes.shopScreen,
page: _i6.ShopScreen,
),
_i1.RouteDef(
ShopNavigationStackScreenRoutes.giftGuideScreen,
page: _i7.GiftGuideScreen,
),
];
final _pagesMap = <Type, _i1.StackedRouteFactory>{
_i6.ShopScreen: (data) {
return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i6.ShopScreen(),
settings: data,
);
},
_i7.GiftGuideScreen: (data) {
final args = data.getArgs<NestedGiftGuideScreenArguments>(nullOk: false);
return _i5.MaterialPageRoute<dynamic>(
builder: (context) =>
_i7.GiftGuideScreen(groupId: args.groupId, key: args.key),
settings: data,
);
},
};
@override
List<_i1.RouteDef> get routes => _routes;
@override
Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap;
}
class NestedGiftGuideScreenArguments {
const NestedGiftGuideScreenArguments({
required this.groupId,
this.key,
});
final String groupId;
final _i5.Key? key;
@override
String toString() {
return '{"groupId": "$groupId", "key": "$key"}';
}
@override
bool operator ==(covariant NestedGiftGuideScreenArguments other) {
if (identical(this, other)) return true;
return other.groupId == groupId && other.key == key;
}
@override
int get hashCode {
return groupId.hashCode ^ key.hashCode;
}
}
class ExploreNavigationStackScreenRoutes {
static const giftGuideScreen = 'gift-guide-screen';
static const all = <String>{giftGuideScreen};
}
class ExploreNavigationStackScreenRouter extends _i1.RouterBase {
final _routes = <_i1.RouteDef>[
_i1.RouteDef(
ExploreNavigationStackScreenRoutes.giftGuideScreen,
page: _i7.GiftGuideScreen,
)
];
final _pagesMap = <Type, _i1.StackedRouteFactory>{
_i7.GiftGuideScreen: (data) {
final args = data.getArgs<NestedGiftGuideScreenArguments>(nullOk: false);
return _i5.MaterialPageRoute<dynamic>(
builder: (context) =>
_i7.GiftGuideScreen(groupId: args.groupId, key: args.key),
settings: data,
);
}
};
@override
List<_i1.RouteDef> get routes => _routes;
@override
Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap;
}
class NestedGiftGuideScreenArguments {
const NestedGiftGuideScreenArguments({
required this.groupId,
this.key,
});
final String groupId;
final _i5.Key? key;
@override
String toString() {
return '{"groupId": "$groupId", "key": "$key"}';
}
@override
bool operator ==(covariant NestedGiftGuideScreenArguments other) {
if (identical(this, other)) return true;
return other.groupId == groupId && other.key == key;
}
@override
int get hashCode {
return groupId.hashCode ^ key.hashCode;
}
}
extension NavigatorStateExtension on _i8.NavigationService {
Future<dynamic> navigateToHomeScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return navigateTo<dynamic>(Routes.homeScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> navigateToShopNavigationStackScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return navigateTo<dynamic>(Routes.shopNavigationStackScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> navigateToExploreNavigationStackScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return navigateTo<dynamic>(Routes.exploreNavigationStackScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> navigateToNestedShopScreenInShopNavigationStackScreenRouter([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return navigateTo<dynamic>(ShopNavigationStackScreenRoutes.shopScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic>
navigateToNestedGiftGuideScreenInShopNavigationStackScreenRouter({
required String groupId,
_i5.Key? key,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return navigateTo<dynamic>(ShopNavigationStackScreenRoutes.giftGuideScreen,
arguments: NestedGiftGuideScreenArguments(groupId: groupId, key: key),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic>
navigateToNestedGiftGuideScreenInExploreNavigationStackScreenRouter({
required String groupId,
_i5.Key? key,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return navigateTo<dynamic>(
ExploreNavigationStackScreenRoutes.giftGuideScreen,
arguments: NestedGiftGuideScreenArguments(groupId: groupId, key: key),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithHomeScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return replaceWith<dynamic>(Routes.homeScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithShopNavigationStackScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return replaceWith<dynamic>(Routes.shopNavigationStackScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithExploreNavigationStackScreen([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return replaceWith<dynamic>(Routes.exploreNavigationStackScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithNestedShopScreenInShopNavigationStackScreenRouter([
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
]) async {
return replaceWith<dynamic>(ShopNavigationStackScreenRoutes.shopScreen,
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic>
replaceWithNestedGiftGuideScreenInShopNavigationStackScreenRouter({
required String groupId,
_i5.Key? key,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return replaceWith<dynamic>(ShopNavigationStackScreenRoutes.giftGuideScreen,
arguments: NestedGiftGuideScreenArguments(groupId: groupId, key: key),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic>
replaceWithNestedGiftGuideScreenInExploreNavigationStackScreenRouter({
required String groupId,
_i5.Key? key,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return replaceWith<dynamic>(
ExploreNavigationStackScreenRoutes.giftGuideScreen,
arguments: NestedGiftGuideScreenArguments(groupId: groupId, key: key),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
}
Expected behavior
No response
Screenshots
No response
Additional Context
No response
You need a unique name if you're using the same types.
I would suggest adding the parent path in front of the name.
Hi Dane, thanks for answering. What you mean for unique name? Can you make an example related to this case? Also what you mean adding parent path in front of the name? Should this fix the issue? Anyway I don't understand why with old version of stacked the generator worked. I mean, I think it is normal to have the same view (gift guide in my case) that exists in different path, in the real world. Unfortunately my company didn't upgrade stacked for more than a year and this is the result...Thanks
@scognito Were you able to solve your issue?
@scognito I agree that it should work.
Me and @ferrarafer will discuss a solution and implement it.
I've just come back from leave so catching up on everything now.
Hi @scognito @coruscant187
The issue was fixed, please let us know if something doesn't work as expected. Sorry for the delay.
@ferrarafer I have a similar issue where the same navigateTo name is created each time the route is added as a nested route of a different section. Using the latest stacked version