Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoRouterDelegate.declarative is deprecated - use guards instead - no docs? #1928

Open
realitymolder opened this issue Apr 17, 2024 · 8 comments

Comments

@realitymolder
Copy link

realitymolder commented Apr 17, 2024

Hey there,
I've tried to use AutoRouterDelegate.declarative on AutoRoute 8, but it seems like it got deprecated.
The deprecation message says that I should use guards instead. My goal here is to create an auth routing by AuthState, but I don't want the app to show me the routing animations between pages when the app will route the user after an auth check.
How should I convert it into guards? I see no docs on the deprecation message or changelog.
P.S due to the fact that I use AutoTabsScaffold I cannot return the HomePage because it has children (is a router of its own).

Code example of the init Widget of the app that should change into guards, apparently.

class HomePage extends HookConsumerWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // Listen to user provider and return relevant screen
    return ref.watch(userControllerProvider).when(
      // Has user - Home screen
      data: (user) {
        // Loading the services in the background
        loadServices(ref, user);
        return userHomePage;
      },
      // Error while loading the user - error screen
      error: (e, s) {
        logger.e('Error Loading Profile $e', stackTrace: s);
        return const ErrorPage();
      },
      // Loading the user - circular loading
      loading: () {
        logger.i('Loading Profile ...');
        return const LoadingPage(shouldload: true);
      },
    );
  }
  }


  /// The home page
  Widget get userHomePage => AutoTabsScaffold(
        extendBody: true,
        backgroundColor: R.colors.white,
        routes: const [
          // MomentsRouter(),
          BrowseRouter(),
          ConnectionsRouter(),
        ],
        resizeToAvoidBottomInset: false,
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: const HomeFloatingActionButton(),
        bottomNavigationBuilder: (context, tabsRouter) =>
            const HomeBottomNavigation(),
      );

Thank you,
D.

@realitymolder
Copy link
Author

@Milad-Akarie

@Milad-Akarie
Copy link
Owner

@realitymolder share your existing implementation using declarative.
fyi it's only deprecated in root scope, you can still use declarative in sub-routers

@realitymolder
Copy link
Author

@realitymolder share your existing implementation using declarative. fyi it's only deprecated in root scope, you can still use declarative in sub-routers

I used it in root, as a routerDelegate:

   routerDelegate: AutoRouterDelegate.declarative(
          _appRouter,
          routes: (_) {
            return auth.when(
              data: (authState) {
                return authState.when(
                  finished: () {
                    ref
                        .read(userControllerProvider.notifier)
                        .getAuthenticatedUser();
                    // if they are logged in and finished , bring them to the Home page:
                    return [const HomeRoute()];
                  },
                  onboarding: () {
                    // if they are logged in but didnt finish , bring them to the Onboarding page
                    return [const OnboardingRoute()];
                  },
                  unAuthenticated: () {
                    // if they are not logged in, bring them to the Login page
                    return [const LoginRoute()];
                  },
                );
              },
          error: (e, s) => [const ErrorRoute()],
          loading: () => [const LoadingRoute()],
        );
        },
        ),
        routeInformationParser:
            _appRouter.defaultRouteParser(includePrefixMatches: true),

@mxknt
Copy link

mxknt commented Apr 26, 2024

@Milad-Akarie Just want to tag along and say that I'm using AutoRouter the exact same way, with a declarative router at the root of my app to handle the auth state. Also curious what the alternative is if this pattern is being deprecated. Thanks for all your work on this awesome library!

@Milad-Akarie
Copy link
Owner

@realitymolder @mxknt you had no problems with deep-linking when working with the root declarative router?

@realitymolder
Copy link
Author

@realitymolder @mxknt you had no problems with deep-linking when working with the root declarative router?

This is a new project, so didn't have a chance yet to get into deep linking. Also, my implementation of the router delegate (root) was very young, and I tried to go with the "best practice" to make sure I solve this issue in the best way possible.
With that said, It is quite an issue due to the fact that it's not a boolean auth but a Tri auth situation and 2 of those are dependent on an async value that comes from the server...

@Milad-Akarie
Copy link
Owner

@realitymolder what you can do is have a sub-router dedicated to auth-flow and guard your home route with an auth guard

@realitymolder
Copy link
Author

realitymolder commented Apr 30, 2024

@realitymolder what you can do is have a sub-router dedicated to auth-flow and guard your home route with an auth guard

I'm trying to implement that now, but it seems like I'm not able to update the state of the guard, like the guard is not listening, although I'm using .watch (riverpod)
Only on hot reload, the app will show the relevant event
example:

class AuthGuard extends AutoRouteGuard {
  AuthGuard({required this.ref});
  final Ref ref;

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) {
    ref.read(authControllerProvider.notifier).loadAuthState();

    logger.d('message from AuthGuard');
    ref.watch(authControllerProvider).when(
          data: (authState) {
            authState.when(
              unAuthenticated: () {
                
                logger.d('unAuthenticated');
                // resolver.redirect(const LoginRoute());
                router.popAndPush(const LoginRoute());
              },
              onboarding: () {
                logger.d('onboarding');
                router.popAndPush(const OnboardingRoute());
                
                // resolver.next(false);
              },
              finished: () {
                logger.d('finished');
                resolver.next();
              },
            );
          },
          error: (error, stackTrace) =>
              logger.e(error.toString(), stackTrace: stackTrace),
          loading: () {
            logger.d('Loading AuthGuard...');
            // ref.read(authControllerProvider.notifier).loadAuthState();
          },
        );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants