1

So I am using a riverpod with ChangeNotifier, GoRouter and Hive

So this is my RouteService class with parameter of HiveBox;

class RouteService extends ChangeNotifier {
  late final Box box;
  bool _initialized = false;
  bool _loginState = false;

  RouteService({required this.box});

  bool get loginState => _loginState;
  bool get initialized => _initialized;
  set loginState(bool value) {
    _loginState = value;
    box.put('login', value);
    notifyListeners();
  }

  set initializedState(bool value) {
    _initialized = value;
    notifyListeners();
  }

  Future<void> onAppStart() async {
    _initialized = box.get('initialized', defaultValue: false);
    _loginState = box.get('login', defaultValue: false);

    await Future.delayed(const Duration(seconds: 2));

    ///TODO set a downloading resources here

    _initialized = true;
    notifyListeners();
  }
}

And this is my BlackboltRouter class which contains the GoRouter and the Ref object from flutter riverpod package. (please focus on redirect)

class BlackboltRouter {
  GoRouter get router => _goRouter;

  BlackboltRouter(this.ref);
  late Ref ref;

  late final GoRouter _goRouter = GoRouter(
    // refreshListenable: routeService,
    initialLocation: APP_PAGE.home.toPath,

routes: [
  ShellRoute(
    builder: (context, state, child) => ResponsiveWrapper.builder(
      ClampingScrollWrapper.builder(context, child),
      maxWidth: 1200,
      minWidth: 480,
      breakpoints: const [
        ResponsiveBreakpoint.resize(480, name: MOBILE),
        ResponsiveBreakpoint.autoScale(600, name: TABLET),
        ResponsiveBreakpoint.resize(1000, name: DESKTOP),
        ResponsiveBreakpoint.autoScale(2460, name: '4K')
      ],
    ),
    routes: [
      GoRoute(
        path: APP_PAGE.home.toPath,
        name: APP_PAGE.home.toName,
        builder: (_, __) => RootPage(),
      ),
      GoRoute(
        path: APP_PAGE.splash.toPath,
        name: APP_PAGE.splash.toName,
        builder: (context, state) => SplashPage(),
      ),
      GoRoute(
        path: APP_PAGE.login.toPath,
        name: APP_PAGE.login.toName,

        // TODO add login page
        builder: (context, state) => SizedBox.shrink(),
      ),
      GoRoute(
        path: APP_PAGE.game.toPath,
        name: APP_PAGE.game.toName,
        builder: (context, state) {
          final questGameKey = state.params['questGameKey'] ?? 'unknown';
          return GamePage(questGameKey: questGameKey);
        },
      ),
    ],
  ),
],

// errorBuilder: (context, state) => ErrorPage(),
redirect: (context, state) {
  final routeService = ref.read(routerServiceProvider);
  final homeLocation = state.namedLocation(APP_PAGE.home.toName);
  final splashLocation = state.namedLocation(APP_PAGE.splash.toName);

  final isInitialized = routeService.initialized;

  final isGoingToInit = state.subloc == splashLocation;

  if (!isInitialized && !isGoingToInit) {
    return splashLocation;
  } else if (!isInitialized && isGoingToInit) {
    return homeLocation;
  }
  return null;
  // return null;
},

); }

This my MyApp class

const MyApp({
    required this.playerProgressPersistence,
    required this.settingsPersistence,
    required this.adsController,
    required this.gamesServicesController,
    required this.questGameBox,
    required this.utilGameBox,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return AppLifecycleObserver(
      child: ProviderScope(
        overrides: [
          gameCategoryRepositoryProvider.overrideWithValue(
            GameCategoryHiveRepository(
              HiveDatabaseGameCategoryApi(questGameBox),
            ),
          ),
          routerServiceProvider.overrideWithValue(
            RouteService(box: utilGameBox),
          ),
        ],
        child: Consumer(builder: (context, ref, _) {
          final goRouter = ref.watch(blackboltRouterProvider);

          return BlackboltWidget(
            title: 'One sound, One word',
            routerConfig: goRouter.router,
          );
        }),
      ),
    );
  }
}

Lastly my providers:

final routerServiceProvider =
    ChangeNotifierProvider<RouteService>((ref) => throw UnimplementedError());

/// The provider for the BlackboltRouter
final blackboltRouterProvider = Provider<BlackboltRouter>((ref) {
  // final routerService = ref.watch(routerServiceProvider);
  return BlackboltRouter(ref);
});

As you can see in our riverpod for the routeServiceProvider, I returned a throw UnimplementedError because I need to pass a value for HiveBox so I decide to throw UnimpletedError first. Then in our MyApp class is that I begin to initialized the Hive boxes and I override the value of my routeServiceProvider. So finally, in my Blackbolt Router I subscribe the routeServiceProvide, which is the expected value of routeServiceProvider is not null. But the error occurs there, it gives me a report that

The following ProviderException was thrown building DefaultSelectionStyle:
An exception was thrown while building ChangeNotifierProvider<RouteService>#c5428.
Thrown exception:
An exception was thrown while building _NotifierProvider<RouteService>#d5e71.
Thrown exception:
UnimplementedError

0 Answers0