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