RouteCollection.fromList constructor

RouteCollection.fromList(
  1. List<AutoRoute> routes, {
  2. bool root = false,
  3. OnGeneratePath onGeneratePath = defaultPathGenerator,
})

Creates a Map of config-entries from routes

also handles validating defined paths and auto-generating the non-defined ones

if this RouteCollection is created by the router root will be true else if it's created by a parent route-entry it will be false

Implementation

factory RouteCollection.fromList(List<AutoRoute> routes,
    {bool root = false, OnGeneratePath onGeneratePath = defaultPathGenerator}) {
  final routesMarkedInitial = routes.where((e) => e.initial);
  throwIf(routesMarkedInitial.length > 1,
      'Invalid data\nThere are more than one initial route in this collection\n${routesMarkedInitial.map((e) => e.name)}');

  final targetInitialPath = root ? '/' : '';
  var routesMap = <String, AutoRoute>{};
  final subCollections = <String, RouteCollection>{};
  var hasValidInitialPath = false;
  for (var r in routes) {
    if (r.hasSubTree) {
      subCollections[r.name] = RouteCollection.fromList(
        r.children!,
        onGeneratePath: onGeneratePath,
      );
    }

    var routeToUse = r;
    if (r._path != null) {
      throwIf(
        !root && r.path.startsWith('/'),
        'Sub-paths can not start with a "/": ${r.path}',
      );
      throwIf(
        root && !r.path.startsWith(RegExp('[/]|[*]')),
        'Root-paths must start with a "/" or be a wild-card:  ${r.path}',
      );
      routeToUse = r;
    } else {
      final String generatedPath;
      if (r.initial) {
        generatedPath = root ? '/' : '';
      } else {
        final path = onGeneratePath(r);
        assert(!path.startsWith('/'),
            '"/" is added automatically based on route level, generated path should not have a leading "/"');
        generatedPath = root ? '/$path' : path;
      }
      routeToUse = r.changePath(generatedPath);
    }
    hasValidInitialPath |= routeToUse.path == targetInitialPath;
    if (routesMap.containsKey(r.name)) {
      throw ArgumentError.value(r.name, 'name', 'Route name must be unique');
    }
    routesMap[r.name] = routeToUse;
  }
  if (!hasValidInitialPath && routesMarkedInitial.isNotEmpty) {
    final redirectRoute = RedirectRoute(
      path: targetInitialPath,
      redirectTo: routesMarkedInitial.first.path,
    );
    routesMap = {
      redirectRoute.name: redirectRoute,
      ...routesMap,
    };
  }
  return RouteCollection(routesMap, subCollections);
}