Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter go_router redirect with object parameter

Normally I can go() to a route, and specify extra to pass an object: void go(String location, {Object? extra}). How can I pass the extra parameter from the GoRoute's redirect?

      GoRoute(
        path: '/',
        redirect: (context, state) async {
          final theObject = tryToGetTheObject();
          if (theObject != null) {
            // context.go("/location", extra: theObject); -> throws error
            // return state.namedLocation("Location", extra: theObject); -> doesn't exist
            return state.namedLocation("Location"); // doesn't allow extra
          }
          return null;
        },
      ),

Alternatively, how can I load the object in the builder, since the (page)Builder may not be async (even though redirect is allowed to be):

      GoRoute(
        path: '/',
        redirect: (context, state) async {
          final theObject = tryToGetTheObject();
          if (theObject != null) {
            return state.namedLocation("Location");
          }
          return null;
        },
      ),
      GoRoute(
        name: 'Location',
        path: '/location',
        builder: (context, state) async { // async not allowed
          final theObject = state.extra ?? await tryToGetTheObject(); // async not allowed
          if (theObject == null) throw Exception("Invalid state");
          return LocationWidget(theObject);
        },
      ),
like image 921
jeffrey.d.m Avatar asked Feb 01 '26 19:02

jeffrey.d.m


1 Answers

This is a simple workaround, if you really need the extra property in the subroute. You can do this by creating an extra variable outside and then assigning it the value from the redirect whenever its needed. This way each time you go to a new route your variable gets overwritten. You can access the variable inside the subrouter to get the extras. Example:

class AppRouter {
  // Your extra variable
  Map<String, dynamic>? _extra;
  
  AppRouter({required this.auth});
  Auth auth;
  
  late GoRouter router = GoRouter(
    refreshListenable: auth,
    redirect: (context, state) {

      // considering the extra is a map
      _extra = state.extra as Map<String, dynamic>?;
      if (auth.isLoggedIn == false) {
        return Login.route;
      }

      if (state.location == "/second-page") {
        return SecondPage.route;
      }

      return Home.route;
    },
    routes: [
      GoRoute(
        path: Login.route,
        name: 'login',
        builder: (context, state) {
          return const Login();
        },
      ),
      GoRoute(
        path: Home.route,
        name: 'Home_page',
        builder: (context, state) {

          // _extra is accessible here
          return Home(myKey: _extra);
        },
      ),
      GoRoute(
        path: SecondPage.route,
        name: 'second_page',
        builder: (context, state) {
          return const SecondPage();
        },
      ),
    ],
    initialLocation: Home.route,
  );
}

like image 144
innocent Avatar answered Feb 04 '26 15:02

innocent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!