navigate<T> method
Function used to navigate pages.
name is the route name that was registered using addRoute.
args are optional arguments that can be passed to the next page.
To retrieve these arguments use args method on NyRouterRoute.
navigationType can be specified to choose from various navigation
strategies such as NavigationType.push, NavigationType.pushReplace,
NavigationType.pushAndRemoveUntil.
removeUntilPredicate should be provided if using
NavigationType.pushAndRemoveUntil strategy.
Returns the result from the navigated page, or null if navigation was
cancelled by a route guard redirect.
Implementation
Future<T?> navigate<T>(
String name, {
NyArgument? args,
NavigationType navigationType = NavigationType.push,
dynamic result,
bool Function(Route<dynamic> route)? removeUntilPredicate,
TransitionType? transitionType,
PageTransitionType? pageTransitionType,
PageTransitionSettings? pageTransitionSettings,
}) async {
assert(
navigationType != NavigationType.pushAndRemoveUntil ||
removeUntilPredicate != null,
);
if (transitionType != null) {
pageTransitionType = transitionType.pageTransitionType;
pageTransitionSettings = transitionType.pageTransitionSettings;
}
Uri? uriSettingName;
try {
uriSettingName = Uri.parse(name);
} on FormatException catch (e) {
NyLogger.error(e.toString());
}
String routeName = name;
if (uriSettingName != null) {
routeName = uriSettingName.path;
}
NyQueryParameters? nyQueryParameters;
if (uriSettingName != null && uriSettingName.queryParameters.isNotEmpty) {
nyQueryParameters = NyQueryParameters(uriSettingName.queryParameters);
}
bool checkRouteNamedArg = isRouteNamedArg(routeName);
if (!checkRouteNamedArg) {
_checkAndThrowRouteNotFound(routeName, args, navigationType);
}
final NyRouterRoute? targetRoute = _findRouteForName(routeName);
_log('Navigating to: $routeName (type: ${navigationType.name})');
// Execute route guards before navigation
if (targetRoute != null) {
final guards = targetRoute.getRouteGuards();
if (guards.isNotEmpty) {
// Create the initial route context
RouteContext currentContext = RouteContext(
context: navigatorKey?.currentContext,
data: args?.data,
queryParameters: nyQueryParameters?.data ?? {},
routeName: routeName,
originalRouteName: name,
);
for (final guard in guards) {
_log('Running route guard: ${guard.runtimeType}');
// Check if this is a new-style NyRouteGuard
if (guard is NyRouteGuard) {
guard.setRouteContext(currentContext);
final result = await guard.onBefore(currentContext);
if (result == GuardResult.handled) {
// Check if guard requested a redirect
if (guard.redirectConfig != null) {
final config = guard.redirectConfig!;
_log('Route guard redirected to: ${config.path}');
final routeData = RouteData.fromRedirectConfig(config);
await routeData.routeToPage();
}
return null;
}
// Pass modified data to next guard
if (guard.hasModifiedData) {
currentContext = currentContext.withData(guard.modifiedData);
// Update args with modified data for the route
args = NyArgument(guard.modifiedData);
}
} else {
// Legacy RouteGuard support
final pageRequest = PageRequest(
context: navigatorKey?.currentContext,
nyArgument: args,
queryParameters: nyQueryParameters?.data,
);
final guardResult = await guard.onRequest(pageRequest);
if (guardResult != null &&
guardResult.isRedirect &&
guardResult.routeData != null) {
_log('Route guard redirected to: ${guardResult.routeData!.path}');
await guardResult.routeData!.routeToPage();
return null;
}
}
}
}
}
final navigationResult = await _navigate(
routeName,
args,
navigationType,
result,
removeUntilPredicate,
pageTransitionType,
pageTransitionSettings,
queryParameters: nyQueryParameters,
originalRouteName: name,
);
// Execute onAfter lifecycle for guards
if (targetRoute != null) {
final afterContext = RouteContext(
context: navigatorKey?.currentContext,
data: args?.data,
queryParameters: nyQueryParameters?.data ?? {},
routeName: routeName,
originalRouteName: name,
);
for (final guard in targetRoute.getRouteGuards()) {
if (guard is NyRouteGuard) {
await guard.onAfter(afterContext);
}
}
}
return navigationResult as T?;
}