csells / go_router

The purpose of the go_router for Flutter is to use declarative routes to reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), handling deep linking from Android, iOS and the web while still allowing an easy-to-use developer experience.
https://gorouter.dev
442 stars 96 forks source link

"Cannot set URL path strategy more than once" #135

Closed nyck33 closed 2 years ago

nyck33 commented 2 years ago

I'm using this with Riverpod so I do in void main:

runApp(
    ProviderScope(
      child: MaterialApp(  //the relevent error causing widget it says here line 98
        debugShowCheckedModeBanner: false,
        title: 'Myapp Mobile and Web',
        home: MyApp(
          ///dummyUser and loggedOut or userSP and loggedIn
          user: mainUser,
          appBarState: _appBarState,
          sideBarState: _sideBarState,
          loginStatus: loginStatus, //dont' need
          sessionValid: sessionValid,
        ),
      ),
    ),
  );

Then MyApp is like:

class MyApp extends ConsumerStatefulWidget {
  final UserSharedPrefs user;
  final AppBarState appBarState;
  final SideBarState sideBarState;
  final LoginStatus loginStatus;
  //session was loaded from SP
  final bool sessionValid;

  const MyApp(
      {Key? key,
      required this.user,
      required this.appBarState,
      required this.sideBarState,
      required this.loginStatus,
      required this.sessionValid})
      : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {
  UserSharedPrefs get _user => widget.user;
  AppBarState get _appBarState => widget.appBarState;
  SideBarState get _sideBarState => widget.sideBarState;
  LoginStatus get loginStatus => widget.loginStatus;
  bool get sessionValid => widget.sessionValid;
  //late final _sessionValid;

  //SideBarState initialSideBarState = SideBarState();

  @override
  void initState() {
    // TODO: implement initState
    //_sessionValid = ref.watch(userProvider.notifier).userService.init();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    /*
    final userProviderState = ref.watch(userProvider);
    final sidebarProviderState = ref.watch(sideBarProvider);
    final appBarProviderState = ref.watch(appBarProvider);
    final userNotifierProvider = ref.watch(userProvider.notifier);
    final sidebarNotifierProvider = ref.watch(sideBarProvider.notifier);
    final appbarNotifierProvider = ref.watch(appBarProvider.notifier);
    //initialize Storage in each controller
    userNotifierProvider.initializeStorage();
    sidebarNotifierProvider.initializeStorage();
    appbarNotifierProvider.initializeStorage();
    //set state loaded from Storage
    userNotifierProvider.initializeUser(_user);
    sidebarNotifierProvider.initializeSideBarState(_sideBarState);
    appbarNotifierProvider.initializeAppBarState(_appBarState);
*/
    return MaterialApp.router(
        routeInformationParser: _router.routeInformationParser,
        routerDelegate: _router.routerDelegate,
        title: 'SmartPMS X');
  }

  //userSharedPrefs dummyUser has loginStatus loggedIn
  final _router = GoRouter(
    initialLocation: pathZeroMap[PathsZero.home]!,
    routes: [
      GoRoute(
        path: pathZeroMap[PathsZero.home]!,
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: MyHomePage(title: 'SmartPMS X'),
        ),
      ),
      GoRoute(
        path: '/login',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: LoginScreen(),
        ),
      ),
      //TODO sub_routes and other routes here
    ],
    errorPageBuilder: (context, state) => MaterialPage<void>(
      key: state.pageKey,
      child: ErrorPage(state.error),
    ),
    urlPathStrategy: UrlPathStrategy.path,  //set here
    debugLogDiagnostics: true,
  );

Where am I setting it twice?

csells commented 2 years ago

You're creating two instances of MaterialApp. The first one sets the URL path strategy for the app and then the second tries to do the same, which is causing the error.