navigate method
Generates a URI string based on the given input. Handy when you have named routes.
Each item in linkParams
should be a Route,
String
or Map<String, dynamic>
.
Strings should be route names, namespaces, or paths. Maps should be parameters, which will be filled into the previous route.
Paths and segments should correspond to the way you declared them.
For example, if you declared a route group on
'users/:id'
, it would not be resolved if you
passed 'users'
in linkParams
.
Leading and trailing slashes are automatically removed.
Set absolute
to true
to insert a forward slash
before the generated path.
Example:
router.navigate(['users/:id', {'id': '1337'}, 'profile']);
Implementation
String navigate(Iterable linkParams, {bool absolute = true}) {
final segments = <String>[];
Router search = this;
Route? lastRoute;
for (final param in linkParams) {
var resolved = false;
if (param is String) {
// Search by name
for (var route in search.routes) {
if (route.name == param) {
segments.add(route.path.replaceAll(_straySlashes, ''));
lastRoute = route;
if (route is SymlinkRoute<T>) {
search = route.router;
}
resolved = true;
break;
}
}
// Search by path
if (!resolved) {
var scanner = SpanScanner(param.replaceAll(_straySlashes, ''));
for (var route in search.routes) {
var pos = scanner.position;
var parseResult = route.parser?.parse(scanner);
if (parseResult != null) {
if (parseResult.successful && scanner.isDone) {
segments.add(route.path.replaceAll(_straySlashes, ''));
lastRoute = route;
if (route is SymlinkRoute<T>) {
search = route.router;
}
resolved = true;
break;
} else {
scanner.position = pos;
}
} else {
scanner.position = pos;
}
}
}
if (!resolved) {
throw RoutingException(
'Cannot resolve route for link param "$param".');
}
} else if (param is Route) {
segments.add(param.path.replaceAll(_straySlashes, ''));
} else if (param is Map<String, dynamic>) {
if (lastRoute == null) {
throw RoutingException(
'Maps in link params must be preceded by a Route or String.');
} else {
segments.removeLast();
segments.add(lastRoute.makeUri(param).replaceAll(_straySlashes, ''));
}
} else {
throw RoutingException(
'Link param $param is not Route, String, or Map<String, dynamic>.');
}
}
return absolute
? '/${segments.join('/').replaceAll(_straySlashes, '')}'
: segments.join('/');
}