navigate method

String navigate(
  1. Iterable linkParams, {
  2. bool absolute = true,
})

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('/');
}