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

auto_route 1.0.0-beta #283

Closed
Milad-Akarie opened this issue Dec 12, 2020 · 30 comments
Closed

auto_route 1.0.0-beta #283

Milad-Akarie opened this issue Dec 12, 2020 · 30 comments

Comments

@Milad-Akarie
Copy link
Owner

Milad-Akarie commented Dec 12, 2020

I just published auto_route 1.0.0-beta with very little documentation, There's still alot of work to be done Docs, Testing and improvements.
I don't seem to get alot of free time lately so I'm asking you to bare with me.
as I said I didn't get the chance to write the docs but If you've used auto_route before, finding your way around shouldn't be hard.
I promise to be more responsive so if you have any questions about the new auto_route you can ask me here.
Thank you all for your patience.
https://pub.dev/packages/auto_route/versions/1.0.0-beta

Highlights

  • deepLinking has never been easier (including same level deep linking)
  • full controller over route stack
  • route redirect
  • custom route builders (not the same as TransitionsBuilders)
  • tidy generated code using code_builder
    _ much more...
@theweiweiway
Copy link
Collaborator

Super excited for this... Can't wait to try it out! Thanks Milad!!

@dgaedcke
Copy link

Thanks for putting this out so quickly ... I'm excited to explore it and learn.

I needed to use: ScaffoldMessenger
which is on the beta branch, so I upgraded my env to:

environment:
sdk: '>=2.10.0 <3.0.0'
flutter: "1.23.0-18.1.pre"

With this config, there are quite a few build errors ... you may want to check it out or I'll report back as I learn more as to what's going on.

@Milad-Akarie
Copy link
Owner Author

Hey @dgaedcke
I have no issues on Channel dev, 1.25.0-8.0.pre.
What kinda error are you getting?

@dgaedcke
Copy link

It was totally user error ... I've not worked with Dart codegen before & I neglected to run pub get inside the generator directory ... looks good now ... about to start testing!!

@dgaedcke
Copy link

It's looking really good so far ... working beautifully!!

First a question: Would it make sense to use the Dart "part of" syntax (in generated file) so that the file with my live RouterConfig (app state) can ALSO export the generated Argument classes?? Or do I need to be importing the generated file everywhere in my project (along with my RouterConfig).
That would seem a bit redundant. Or perhaps I don't fully understand the Dart "export" syntax because I've only seen it, or gotten it to work in the presence of a library

One issue I've hit (that I can work around) but others may need this....
How do you pass argument data to the INITIAL screen?
This setup is not working even though "Prospect.seed" is the correct argument for me HomeScreen

final tsRouter = context.read(tsRouterProvider); return MaterialApp.router( title: "Touchstone Routing", routerDelegate: RootRouterDelegate(tsRouter), routeInformationParser: tsRouter.nativeRouteParser, // routeInformationProvider: PlatformRouteInformationProvider( initialRouteInformation: RouteInformation(location: '/', state: Prospect.seed), ), // backButtonDispatcher: getRbbd(), );

Ah doh, I've switched to using the argument wrapper ... like this:
initialRouteInformation: RouteInformation( location: '/', state: DashboardArgs(prospect: Prospect.seed), ),

but I'm still getting this error:

Unhandled Exception: DashboardArgs can not be null because it has required parameters
E/flutter (32561): #0 RouteData.getArgs

@Milad-Akarie
Copy link
Owner Author

The part-of syntax does not work because the generated file does alot of imports. Part files can not have their own imports.
What you can do is export the generated file from your router_comfig and import ot instead

@Milad-Akarie
Copy link
Owner Author

Milad-Akarie commented Dec 13, 2020

You don't need to use a route provider to set initial destination.
Try this:
RootRouterDelegate(rc, defaultHistory:[ DashboardRoute(Args) ])

P.s root back button dispatcher is provided by material App by default

@dgaedcke
Copy link

ah beautiful ... that makes perfect sense ... thanks!!

@rlee1990
Copy link

Has anyone tried using this with Firebase auth? Don't know if it's me or not but the load time to redirect and check for auth, or not is too long also when I refresh the login screen shows then the home screen will show as I am logged in. This works great without the router guards and the need for a redirect

@dgaedcke
Copy link

I'm sure this is a beginner mistake, but my Snackbars are showing behind the soft keyboard. Since no one on Stack Overflow seems to have had that specific problem in over 2-3 years, I'm guessing it's something I'm doing wrong.

I'm using the "currentContext" of your navigatorKey and since it's "UP" the widget tree by 3 or 4 screens (meaning it's NOT the context of my current top screen), I'm guessing that is my problem??

Is there any best practice you'd recommend for showing Snackbars when I'm outside of the build-context?? Or does auto-router have any tricks to do it???

@dgaedcke
Copy link

dgaedcke commented Dec 18, 2020

This might be a bug ...

From my generated code:
class TsRouterConfig extends _i1.AutoRouterConfig {
TsRouterConfig();
}
Note that SUPER is not called from the above constructor

when I look at source for AutoRouterConfig, I see this:
@mustCallSuper
AutoRouterConfig() {
assert(routes != null);
routeCollection = RoutesCollection.from(routes);
root = RouterNode()

so it seems that root is not being initialized??
I'm using the router outside of the build method (no immediate context) so I'm fetching my router from a Provider/Riverpod wrapper ... but when it comes from there, but Nav operations (via the "root" property) are not happening ... seems like no one is getting the msg, but surprisingly, I'm not getting a "called method on null" error

all thoughts welcome!

ah ... nevermind ... I just learned about IMPLICIT superclass execution ... so that explains the no "on null" error but not why nav is not happening...

@Milad-Akarie
Copy link
Owner Author

Has anyone tried using this with Firebase auth? Don't know if it's me or not but the load time to redirect and check for auth, or not is too long also when I refresh the login screen shows then the home screen will show as I am logged in. This works great without the router guards and the need for a redirect

@rlee1990 Are you you doing a network call inside of AutoRouteGuard? please share some code.

@Milad-Akarie
Copy link
Owner Author

@dgaedcke Exactly, no-param super constructors will be called implicitly.
The RootRouteDelegate should rect to root router state changes so be sure the pass your config class to it first.

@Milad-Akarie
Copy link
Owner Author

I'm sure this is a beginner mistake, but my Snackbars are showing behind the soft keyboard. Since no one on Stack Overflow seems to have had that specific problem in over 2-3 years, I'm guessing it's something I'm doing wrong.

I'm using the "currentContext" of your navigatorKey and since it's "UP" the widget tree by 3 or 4 screens (meaning it's NOT the context of my current top screen), I'm guessing that is my problem??

Is there any best practice you'd recommend for showing Snackbars when I'm outside of the build-context?? Or does auto-router have any tricks to do it???

@dgaedcke I'm not sure I understand the issue here but your App can not display anything above The System's keyboard unless maybe a system toast(Android).
if you don't have access to the nearest scaffold's context you could use a global key to access your scaffold' state.

@Milad-Akarie
Copy link
Owner Author

Milad-Akarie commented Dec 19, 2020

A new build is published on pub, it includes TabsRouter support + some changes.
https://pub.dev/packages/auto_route/versions/1.0.0-beta.1
Example App
https://github.com/Milad-Akarie/auto_route_library/tree/master/example/lib/mobile

@dgaedcke
Copy link

dgaedcke commented Dec 19, 2020

Thanks for the update!! What happened to the "copyWith" method on route arguments?? We need this for when an incomplete route is passed??

And do you have any tricks for solving the issue of the xxx.g.dart file being out of sync with the new package so the project won't build?? I just commented out all the places causing build errors but that's a bit cumbersome.

@dgaedcke
Copy link

Seems like "getArgs" has disappeared ... it's breaking the generated code

image

@Milad-Akarie
Copy link
Owner Author

@dgaedcke you need to upgrade the generator as well. Args are merged with route info now.

@dgaedcke
Copy link

dgaedcke commented Dec 19, 2020

have access to the nearest scaffold's context you could use a global key to access your scaffold' state

Yeah, my question was not very clear ... let me try rephrasing it.

The widget tree looks (roughly) like this:

  • MaterialApp
  • AutoRouter
  • Navigator (From AutoRoute with a global key)
  • stack of pages [S1, S2, S3]

So here's the question:
Is it safe for me to show snackbars and dialogs using the context of the Navigator (via the global key)
rather than the context of S3 (or S1 & S2)??

@twister21
Copy link

Do you plan to implement deferred/lazy loading for the TabsRouter? Currently, all widgets that are passed to the router are initialized at once. @Milad-Akarie

@Milad-Akarie
Copy link
Owner Author

Milad-Akarie commented Dec 20, 2020

@dgaedcke how are you obtaining the context of the navigator?
regarding snackbars, I haven't got the chance to play with the Scaffold Messenger yet.

@Milad-Akarie
Copy link
Owner Author

@jonasbeyer as a matter of fact I did and it's now an option in AutoTabsRouter and is set to true by default.
check it out!
https://pub.dev/packages/auto_route/versions/1.0.0-beta.2
https://pub.dev/packages/auto_route_generator/versions/1.0.0-beta.2

@dgaedcke
Copy link

@dgaedcke how are you obtaining the context of the navigator?
regarding snackbars, I haven't got the chance to play with the Scaffold Messenger yet.

I'm reading it right off the generated router as follows:
autoStackRouter.navigatorKey

@dannnnthemannnn
Copy link

dannnnthemannnn commented Dec 21, 2020

I'm getting an issue when running the generation:

% flutter pub run build_runner build
[INFO] Generating build script...
[INFO] Generating build script completed, took 688ms

[INFO] Initializing inputs
[INFO] Reading cached asset graph...
[INFO] Reading cached asset graph completed, took 321ms

[INFO] Checking for updates since last build...
[INFO] Checking for updates since last build completed, took 2.0s

[INFO] Running build...
[INFO] 1.1s elapsed, 0/1 actions completed.
[INFO] 2.1s elapsed, 0/1 actions completed.
[INFO] 3.2s elapsed, 0/1 actions completed.
[INFO] 4.2s elapsed, 0/1 actions completed.
[INFO] 5.4s elapsed, 0/1 actions completed.
[INFO] 6.4s elapsed, 0/1 actions completed.
[INFO] 24.7s elapsed, 0/1 actions completed.
[WARNING] No actions completed for 24.7s, waiting on:
  - auto_route_generator:autoRouteGenerator on lib/routing/router.dart

[SEVERE] auto_route_generator:autoRouteGenerator on lib/routing/router.dart:

type 'DefaultFormalParameterImpl' is not a subtype of type 'AnnotatedNode' in type cast
[INFO] 26.1s elapsed, 3/3 actions completed.
[INFO] 27.7s elapsed, 4/4 actions completed.
[INFO] Running build completed, took 28.2s

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 175ms

[SEVERE] Failed after 28.4s
pub finished with exit code 1

EDIT: Working now. It appears I needed to change my @QueryParam() and @PathParam() imports to match the newest version.
Old: import 'package:auto_route/auto_route_annotations.dart';
New: import 'package:auto_route/auto_route.dart';

@rlee1990
Copy link

Has anyone tried using this with Firebase auth? Don't know if it's me or not but the load time to redirect and check for auth, or not is too long also when I refresh the login screen shows then the home screen will show as I am logged in. This works great without the router guards and the need for a redirect

@rlee1990 Are you you doing a network call inside of AutoRouteGuard? please share some code.

So the issue is for me. I use firebase auth and use route guards

class AuthGuard extends AutoRouteGuard { BuildContext context; AuthGuard(this.context); @override Future<bool> canNavigate(List<PageRouteInfo> routes, RoutingController router) async { // await Future.delayed(Duration(seconds: 2)); print(FirebaseAuth.instance.currentUser); if (FirebaseAuth.instance.currentUser == null) { print('first auth == null'); await router.push( LoginViewRoute(onResult: (loggedIn) { if (loggedIn) { print('first auth'); router.popAndPushAll(routes); } }) ); print('second auth == null'); return false; } print('auth check from outside'); return true; }

My Issue is when I using this package there is a delay and it first will return false then true and on web it will always return false when closing the browser even in prod. When I set up navigation using https://www.filledstacks.com/post/flutter-web-advanced-navigation/ instructions it works the way it should with this code
Route<dynamic> generateRoute(RouteSettings settings) { var routingData = settings.name.getRoutingData; return getPageRoute( StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, AsyncSnapshot<User> snapshot) { if (snapshot.hasError) { return Center( child: Container( child: Text('Sorry: ${snapshot.error}'), ), ); } if (snapshot.connectionState == ConnectionState.waiting) { print('loading'); return Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } if (snapshot.hasData) { print('Auth'); switch(routingData.route) { case HomeRoute: return HomeScreen(); case ServicesRoute: return ServiceScreen(); case ContactRoute: return ContactUsScreen(); case TeamRoute: return Container(); default: return Center( child: Container( child: Text('Sorry: ${settings.name} was not found'), ), ); } } else { print('Null'); switch(routingData.route) { case HomeRoute: return HomeScreen(); case ServicesRoute: return Redirect(); case ContactRoute: return Redirect(); case TeamRoute: return Redirect(); default: return Center( child: Container( child: Text('Sorry: ${settings.name} was not found'), ), ); } } }, ), settings ); }

@aytunch
Copy link

aytunch commented Jan 5, 2021

@Milad-Akarie is there a suggested way to integrate a splash page with this library? what do you use along with the new auto_rote for instance. I have many blocs living above the MaterialPage and I want to show the splash page while some of the async calls are finished and UI is ready to be showed. At that point I want to route to the related page

@theweiweiway
Copy link
Collaborator

You can wrap your MainApp entry point inside of a FutureBuilder that initializes everything, as well as retrieves the correct deep link. If the future is not completed, show splashscreen. Else you can show the MaterialApp.router and route to the deep link you have

@Milad-Akarie
Copy link
Owner Author

@aytunch what @theweiweiway suggested is very valid but when I don't have a fancy splash screen with animations and stuff,
what I like to do is use a native splash screen instead of a flutter widget because it gives a sense of native App opening also, no white screen before flutter is initialized which I find really annoying.

refer to this link to see how you can add a native splash screen to your Flutter App
https://flutter.dev/docs/development/ui/advanced/splash-screen
if you're convinced but lazy you could use this package (haven't tried it but it has some good ratings)
https://pub.dev/packages/flutter_native_splash

Future<void> main() async {
  // native splash screen is on
  await initliazation...
  
 // flutter will draw first frame after this point
 // and native splash screen will disappear
//
 // you can decide what route to start with and 
// pass it to your App
  runApp(MyApp(initialRoute: MyInitialRoute()));
}

and your App should look something like this

class MyApp extends StatelessWidget {
  final PageRouteInfo initialRoute;
   MyApp({Key key, this.initialRoute}) : super(key: key);

  final appRouter = AppRouter();

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
     // pass your route here
      routerDelegate: appRouter.delegate(initialRoutes: [initialRoute]),
      routeInformationParser: appRouter.defaultRouteParser(),
.....

@dgaedcke
Copy link

dgaedcke commented Jan 5, 2021

I'm probably not using this right, but using Riverpod, I'm set up like this:

final tsRouteConfig = Provider<AutoRouterConfig>((ref) {
  return TsRouterConfig();
});

final tsRouterProvider = Provider<StackRouter>((ref) {
  return ref.watch(tsRouteConfig).root;
});

On beta-6, "AutoRouterConfig" is no longer available.
Can you tell me the name of the new type??

@theweiweiway
Copy link
Collaborator

closing due to:

  • stale thread

@dgaedcke if you are still having problems, please feel free to open a new issue

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

7 participants