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
441 stars 97 forks source link

Can't access an instance member in an initializer for redirection example #137

Closed nyck33 closed 3 years ago

nyck33 commented 3 years ago

I tried to copy that one like this:

class SmartPMSApp extends ConsumerWidget {
  SmartPMSApp(
      {Key? key,
      required this.user,
      required this.appBarState,
      required this.sideBarState,
      required this.loginStatus,
      required this.sessionValid})
      : super(key: key);
  final UserSharedPrefs user;
  final AppBarState appBarState;
  final SideBarState sideBarState;
  final LoginStatus loginStatus;
  //session was loaded from SP
  final bool sessionValid;
  //changenotifier from go_router example
  final loginInfo = LoginInfo();

  //LoginInfo get _loginInfo => loginInfo;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    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);
    //final sessionNotifierProvider = ref.watch(sessionProvider.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);
    if (sessionValid) {
      //for go_router
      //sessionNotifierProvider.setSessionInvalid();
      loginInfo.login();
    }

    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) {
            return 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),
    ),
    redirect: (state) {},
    refreshListenable: loginInfo,
    //urlPathStrategy: UrlPathStrategy.path,
    debugLogDiagnostics: true,
  );
}

But it's telling me I cannot access loginInfo. Why is that?

nyck33 commented 3 years ago

The example redirection.dart looks like

/// sample app using redirection to another location
class App extends StatelessWidget {
  App({Key? key}) : super(key: key);

  final loginInfo = LoginInfo();

  // add the login info into the tree as app state that can change over time
  @override
  Widget build(BuildContext context) => ChangeNotifierProvider<LoginInfo>.value(
        value: loginInfo,
        child: MaterialApp.router(
          routeInformationParser: _router.routeInformationParser,
          routerDelegate: _router.routerDelegate,
          title: 'GoRouter Example: Redirection',
          debugShowCheckedModeBanner: false,
        ),
      );
.
.
.

loginInfo looks like an instance member there too but it can be accessed. What's the difference between the example and mine?

csells commented 3 years ago

What's the error?

nyck33 commented 3 years ago

@csells

The instance member 'loginInfo' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expressiond
csells commented 3 years ago

Try replacing this:

final _router = GoRouter(...)

With this:

late final _router = GoRouter(...)

nyck33 commented 3 years ago

Thank you Mr. Sells, I apologize for not being more experimental. I was being lazy, get it?