-
Notifications
You must be signed in to change notification settings - Fork 60
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
☂️ API naming #19
Comments
I like |
I like
I can go with
Just
For me,
This one is the least obvious to me. I actually had to look at StackNavigator in code to figure out what it was doing. When I think of a stack I automatically think of a Flutter Stack or IndexStack widget rather than the route history. I am assuming that StackNavigator would be used in tandem with PageView/TabView/IndexedStack/Stack - anywhere that you would want to reflect back to the URL using some type of controller. Looking at an example implementation: Maybe |
Thank you for your feedback!
I feel like I don't want to go too close to web dev, but I'm not quite sure why 😁 I guess it's because when running not as a web app, there's no URL as such... urgh... naming is hard! Mostly I've tried to find examples in Flutter to copy. Possibly
I like
I originally had
I strongly agree; I really don't like the naming of this. I guess another option would be |
/// flutter modular
@override
final List<ModularRoute> routes = [
ChildRoute(
'/home',
child: (context, args) => HomePage(),
guards: [AuthGuard()],
/// Route here if guard fails.
guardedRoute: '/login',
),
];
/// beamer
@override
List<BeamGuard> get guards => [
BeamGuard(
pathBlueprints: ['/books/*'],
check: (context, location) => location.pathParameters['bookId'] != '2',
/// Route here if guard fails.
showPage: forbiddenPage,
),
]; I don't necessarily agree with this pattern because it's a bit inflexible. There are many reasons why a guard might fail and this pattern locks you into a many-to-one error to page redirect pattern. This is also a departure from Angular's Maybe '/protected-route': (route) => Guard(
canNavigate: (route, context) => canUserAccessPage() ? null : '/no-access',
canNavigateFallback: '/no-access',
builder: (route, context) => MaterialPage(child: ProtectedPage()),
) qlevar_router and vrouter have different implementations but the end result is the same: they allow the guard function to return a url to redirect or nothing. /// qlevar
class AuthMiddleware extends QMiddleware{
final dataStorage = // Get you Data storage
@override
bool canPop() => dataStorage.canLeave;
/// Route here if guard fails.
@override
Future<String?> redirectGuard(String path) async => dataStorage.isLoggedIn ? null: '/parent/child-2';
}
/// vrouter
class Example extends StatelessWidget {
@override
Widget build(BuildContext context) {
return VRouter(
debugShowCheckedModeBanner: false,
routes: [
VWidget(path: '/login', widget: LoginScreen(login)),
VGuard(
/// Route here if guard fails.
beforeEnter: (vRedirector) async =>
isLoggedIn ? null : vRedirector.push('/login'),
stackedRoutes: [VWidget(path: '/home', widget: HomeScreen(logout))],
),
],
);
}
} The idea of the redirector seems a bit unnecessary compared to just returning a url to redirect. A similar pattern played out here might be something like: '/protected-route': (route) => Guard(
canNavigate: (route, context) => canUserAccessPage() ? null : '/no-access',
builder: (context) => MaterialPage(child: ProtectedPage()),
) I must admit I'm a bigger fan of the flexibility of this pattern in comparison to the first set of examples, especially when complex routing scenarios come into play. Maybe the best of both words is to change the relationship between Guard and MaterialPage. var map = {
'/protected-route': (route) => MaterialPage(
child: ProtectedPage(),
guards: [
Guard(
canNavigate: (route, context) => isLoggedIn(),
canNavigateFallback: '/login',
),
Guard(
canNavigate: (route, context) => canUserAccessPage(),
canNavigateFallback: '/no-access',
)
],
)
}; This allows each route to have as many guards as it wants, and each guard to be 1-1. |
Well, I'm now wondering if we need I'm going to add a '/book/:id': (route) => Guard(
validate: (info, context) => booksDatabase.books.any(
(book) => book.id == info.pathParameters['id'],
),
builder: () => MaterialPage(
child: BookPage(id: route.pathParameters['id']!),
),
) You can just do: '/book/:id': (route) =>
booksDatabase.books.any((book) => book.id == route.pathParameters['id'])
? MaterialPage(child: BookPage(id: route.pathParameters['id']!))
: NotFound() Your example above could be written as: '/protected-route': (route) {
if (!isLoggedIn()) return Redirect('/login');
if (!canUserAccessPage) return Redirect('/no-access');
return ProtectedPage();
},
I think it's worth keeping |
The other option is allowing a '/book/:id': (route) {
if (_canShowPage())
return MaterialPage(child: BookPage(id: route.pathParameters['id']!));
}, ...but I'm not really a fan of this. |
I agree, that given the declarative, React-like nature of Flutter, you can probably get by w/o Guards. Looking at how React Router works <Switch>
<Route path="/public">
<PublicPage />
</Route>
<Route path="/login">
<LoginPage />
</Route>
<PrivateRoute path="/protected">
<ProtectedPage />
</PrivateRoute>
</Switch>
|
StackNavigator
PagesNavigator
orPageStackNavigator
Guards
validate
could becanNavigate
onValidationFailed
would need to change toDelegate
routesBuilder
could bemapBuilder
,builder
orrouteMapBuilder
RouteData
PathInfo
path
- could beroute
orurl
Current plan for 0.8.0
StackNavigator
toPageStackNavigator
validate
tocanNavigate
andonValidationFailed
toonNavigationFailed
for anyone who really wants to use themThe text was updated successfully, but these errors were encountered: