defaultGenerateInitialRoutes method Null safety

List<Route> defaultGenerateInitialRoutes(
  1. NavigatorState navigator,
  2. String initialRouteName
)

Turn a route name into a set of Route objects.

This is the default value of onGenerateInitialRoutes, which is used if initialRoute is not null.

If this string starts with a / character and has multiple / characters in it, then the string is split on those characters and substrings from the start of the string up to each such character are, in turn, used as routes to push.

For example, if the route /stocks/HOOLI was used as the initialRoute, then the Navigator would push the following routes on startup: /, /stocks, /stocks/HOOLI. This enables deep linking while allowing the application to maintain a predictable route history.

Implementation

static List<Route<dynamic>> defaultGenerateInitialRoutes(NavigatorState navigator, String initialRouteName) {
  final List<Route<dynamic>?> result = <Route<dynamic>?>[];
  if (initialRouteName.startsWith('/') && initialRouteName.length > 1) {
    initialRouteName = initialRouteName.substring(1); // strip leading '/'
    assert(Navigator.defaultRouteName == '/');
    List<String>? debugRouteNames;
    assert(() {
      debugRouteNames = <String>[ Navigator.defaultRouteName ];
      return true;
    }());
    result.add(navigator._routeNamed<dynamic>(Navigator.defaultRouteName, arguments: null, allowNull: true));
    final List<String> routeParts = initialRouteName.split('/');
    if (initialRouteName.isNotEmpty) {
      String routeName = '';
      for (final String part in routeParts) {
        routeName += '/$part';
        assert(() {
          debugRouteNames!.add(routeName);
          return true;
        }());
        result.add(navigator._routeNamed<dynamic>(routeName, arguments: null, allowNull: true));
      }
    }
    if (result.last == null) {
      assert(() {
        FlutterError.reportError(
          FlutterErrorDetails(
            exception:
              'Could not navigate to initial route.\n'
              'The requested route name was: "/$initialRouteName"\n'
              'There was no corresponding route in the app, and therefore the initial route specified will be '
              'ignored and "${Navigator.defaultRouteName}" will be used instead.',
          ),
        );
        return true;
      }());
      result.clear();
    }
  } else if (initialRouteName != Navigator.defaultRouteName) {
    // If initialRouteName wasn't '/', then we try to get it with allowNull:true, so that if that fails,
    // we fall back to '/' (without allowNull:true, see below).
    result.add(navigator._routeNamed<dynamic>(initialRouteName, arguments: null, allowNull: true));
  }
  // Null route might be a result of gap in initialRouteName
  //
  // For example, routes = ['A', 'A/B/C'], and initialRouteName = 'A/B/C'
  // This should result in result = ['A', null,'A/B/C'] where 'A/B' produces
  // the null. In this case, we want to filter out the null and return
  // result = ['A', 'A/B/C'].
  result.removeWhere((Route<dynamic>? route) => route == null);
  if (result.isEmpty) {
    result.add(navigator._routeNamed<dynamic>(Navigator.defaultRouteName, arguments: null));
  }
  return result.cast<Route<dynamic>>();
}