I'm trying to implement flutter navigation with the autoroute package. For the login flow, I was trying to use autoroute's Declarative Routing method. Authentication logic seems to work fine but I keep getting this exception when the AppState Object change. Can't figure out what I'm doing wrong here.
It's doesn't look like a package issue because I tried a few different old versions too. But got the same exception. However, I'm not entirely sure about it so I already open an issue in the package GitHub page.
Exception
════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for _DeclarativeAutoRouterDelegate:
setState() or markNeedsBuild() called during build.
This Router<Object> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: Router<Object>
dependencies: [UnmanagedRestorationScope]
state: _RouterState<Object>#f02e7
The widget which was currently being built when the offending call was made was: StackRouterScope
When the exception was thrown, this was the stack
#0 Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4305
#1 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4320
#2 State.setState
package:flutter/…/widgets/framework.dart:1108
#3 _RouterState._handleRouterDelegateNotification
package:flutter/…/widgets/router.dart:717
#4 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:308
#5 AutoRouterDelegate._handleRebuild
package:auto_route/…/controller/auto_router_delegate.dart:120
#6 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:308
#7 NavigationHistory._onNewUrlState
package:auto_route/…/controller/navigation_history.dart:26
#8 NativeNavigationHistory._onNewUrlState
package:auto_route/…/controller/navigation_history.dart:120
#9 StackRouter.updateDeclarativeRoutes
package:auto_route/…/controller/routing_controller.dart:954
#10 _AutoRouteNavigatorState._updateDeclarativeRoutes
package:auto_route/…/widgets/auto_route_navigator.dart:46
#11 _AutoRouteNavigatorState.didUpdateWidget
package:auto_route/…/widgets/auto_route_navigator.dart:57
#12 StatefulElement.update
package:flutter/…/widgets/framework.dart:4855
#13 Element.updateChild
package:flutter/…/widgets/framework.dart:3412
#14 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4690
#15 Element.rebuild
package:flutter/…/widgets/framework.dart:4355
......................................................etc....................................................................
#273 Element.updateChild
package:flutter/…/widgets/framework.dart:3412
#274 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4690
#275 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4840
#276 Element.rebuild
package:flutter/…/widgets/framework.dart:4355
#277 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2620
#278 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#279 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:319
#280 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1143
#281 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1080
#282 SchedulerBinding.scheduleWarmUpFrame.<anonymous closure>
package:flutter/…/scheduler/binding.dart:863
(elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)
The _DeclarativeAutoRouterDelegate sending notification was: Instance of '_DeclarativeAutoRouterDelegate'
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by foundation library ════════════════════════════════
setState() or markNeedsBuild() called during build.
APP Main
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late AppRouter _appRouter;
late AppState _appState;
@override
void initState() {
super.initState();
_appRouter = AppRouter();
_appState = AppState();
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<AppState>(create: (_) => _appState),
],
child: Builder(
builder: (BuildContext context) {
return MaterialApp.router(
title: 'My App',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routerDelegate: AutoRouterDelegate.declarative(
_appRouter,
routes: (_) => [
if (!context.watch<AppState>().initialized) const SplashRoute()
else if (!context.watch<AppState>().loginState) const LogInRoute()
else const HomeRoute()
]),
routeInformationParser: _appRouter.defaultRouteParser(),
);
}
),
);
}
}
APP Router
@MaterialAutoRouter(
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(page: SplashPage, initial: true),
AutoRoute(page: HomePage, path: homeRoutePath),
AutoRoute(page: LogInPage, path: loginRoutePath),
AutoRoute(page: SignUpPage, path: signUpRoutePath),
AutoRoute(page: SettingsPage, path: settingsRoutePath),
AutoRoute(page: NotFoundPage, path: "/404"),
RedirectRoute(path: '*', redirectTo: "/404")
],
)
class $AppRouter {}
Flutter Doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version 10.0.19043.1348], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.11.5)
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.62.3)
[√] Connected device (4 available)
• No issues found!
I'm Using Auto Route version => 3.1.3
Thanks.