Very cosmetic, but it might be necessary :
I updated the ```canAccess``` method second signature name and type in the provided sample. As it stands, it triggers `TS(2345): Argument of type 'Route' is not assignable to parameter of type 'string'`.
PR Close#49140
The details of this commit are pretty thoroughly described in the tests
and code comments. In short, it is sometimes ambiguous where to apply commands in
a `SegmentGroup` tree that is created from an `ActivatedRoute` when
dealing with empty paths. This adjusts the strategy to tolerate more
ambiguity while still allowing developers to be explicit.
This is a fix-forward for b/265215141
PR Close#48734
Working towards removing the backwards dependency on router from the
navigation transition handler, this change moves `rootComponentType` and
`afterPreactivation` to the transition handler since that is the only
location those properties are used.
PR Close#48475
The router's `initialNavigation` causes an imperative navigation using
the `navigateByUrl` method. This, however, results in the history state
being removed on a page refresh. This change calls `scheduleNavigation`
directly from `initialNavigation` to ensure the history state is correctly
retained.
PR Close#48540
The ESM js files need to be referenced, and the router tests rely
on `async/await` with change detection- so a special rule is required
that downlevels `async/await` to generators (similar to the Angular CLI)
PR Close#48521
Since we generate a `.mjs` file as entry-point for jasmine tests,
a couple of issues prevented the transitive dependencies from
bootstrap targets to be brought in (causing resolution errors):
1. The `_files` (previously `_esm2015`) targets are no longer needed,
and they also miss all the information on runfiles.
2. The aspect for computing linker mappings does not respect the
`bootstrap` attribute from the `spec_entrypoint` so we manually
add the extract ESM output targets (this rule works with the aspect
and forwards linker mappings).
PR Close#48521
For every `ts_library` target we expose a shorthand that grants
access to the JS files because `DefaultInfo` of a ts library
only exposes the `.d.ts` files.
We rename this away from `es2015` since in practice it's a much
higher target these days. Additionally we no longer use the devmode
output but rather use the prodmode output which has the explicit
`.mjs` output- compatible with ESM.
PR Close#48521
This commit adds a swappable provider for an upcoming change to the
implementation of `Router#createUrlTree`. This will be a breaking change
and is planned to be included in V16.
PR Close#47988
The argument against this feature:
Firstly, this isn't a navigation strategy that's very commonly desired.
Secondly, the hash strategy is a location configuration in `@angular/common`
and you can use it outside of the Router or with any custom router implementations.
So while the net effect of using the router is that it updates the URL which is
controlled by the strategy, this feature provider doesn't necessarily need to
exist in the Router. The location strategy is an application-wide configuration
and affects anything that imports `Location`. Of course, the Router does this
in a few places but plenty of other things might as well.
The argument for this feature:
* Discoverability. While `LocationStrategy` is technically in `@angular/common`, the most
common use-case _is_ when using it with the Router.
* Precedence in the `RouterModule.forRoot([], {useHash: true})`
* Precedence in other routing libraries (`createWebHashHistory` in VueJS
and `HashRouter` in React, for example)
* The implementation of `withHashLocation` is much more clear than
`useHash` was. You can look at the function and see that all it's
doing is adding the `HashLocationStrategy` to the providers list.
resolves#48295 / #47986
PR Close#48301
This commit updates an internal `isStandalone` function and exposes it as a public API,
so that it can be used in applications code.
fixes#47919
PR Close#48114
This commit removes the unnecessary `assignExtraOptionsToRouter` helper
function. This helper is not necessary because the options can be
retrieved from DI and assigned during the construction on the Router.
PR Close#48215
The Router constructor and `setupRouter` factory mainly exist as a
legacy configuration. Since the Router's creation, the style in Angular
has evolved quite a bit. This commit eliminates and cleans up some
unnecessary comlicated code paths related to the router
constructor/factory.
Note that there are edits to the `setupTestingRouter` that could be seen
as breaking. However, it is not for several reasons:
1. The function is documented as a factory function. If used as
documented, the parameters should match what's available in DI
2. The function is totally unused by the Router itself and is not used
in g3 either. I believe it was made publicApi by an error when
updating documentation annotations long ago.
PR Close#48215
This option has already been removed from availability externally. Internally, the last use has been removed
for the type on Route.loadChildren. More testing will be necessary to verify nothing relies on the other
code paths.
PR Close#48292
The navigationId is really just a count of how many navigations have been
processed through the navigation pipeline. This tracking should be
done as part of the navigation transition handler
PR Close#48202
Rather than accessing router internal properties that are available in DI,
this commit directly injects those dependencies in the navigation transition
handler. Note that there are several other items that _should_ be injectable
in DI (like the TitleStrategy) but because those are part of the Router public
interface and writeable(!), they might be changed during runtime. We
have to get these other items from the Router for now...
PR Close#48202
Remove the NgModuleRef from the internal interface of the Router. This
was only used to get the injector (equivalent to EnvironmentInjector).
Instead, the navigation transition handler can directly inject the
EnvironmentInjector
PR Close#48202
The ConfigLoader is only used as part of the navigation transition.
Moving the loader there completes the removal of event triggering in
the router code. This all now lives in the transition handler (plus
the router scroller, but let's ignore that...).
PR Close#48202
The events observable is part of the lifecycle of a navigation. This should
be contained in the NavigationTransitions class rather than the Router.
This Subject is re-exported by the router as an observable to maintain
the public API
PR Close#48202
The navigationId is really just a count of how many navigations have been
processed through the navigation pipeline. This tracking should be
done as part of the navigation transition handler
PR Close#48202
Rather than accessing router internal properties that are available in DI,
this commit directly injects those dependencies in the navigation transition
handler. Note that there are several other items that _should_ be injectable
in DI (like the TitleStrategy) but because those are part of the Router public
interface and writeable(!), they might be changed during runtime. We
have to get these other items from the Router for now...
PR Close#48202
Remove the NgModuleRef from the internal interface of the Router. This
was only used to get the injector (equivalent to EnvironmentInjector).
Instead, the navigation transition handler can directly inject the
EnvironmentInjector
PR Close#48202
The ConfigLoader is only used as part of the navigation transition.
Moving the loader there completes the removal of event triggering in
the router code. This all now lives in the transition handler (plus
the router scroller, but let's ignore that...).
PR Close#48202
The events observable is part of the lifecycle of a navigation. This should
be contained in the NavigationTransitions class rather than the Router.
This Subject is re-exported by the router as an observable to maintain
the public API
PR Close#48202
As mentioned in #46021, `canMatch` guards can replace `canLoad`. There
are slight differences between the two but the purpose of preventing
user access to feature modules is still achievable. There are several
reasons keeping `CanLoad` around is detrimental to the API surface:
* Lazy loading should not be an architectural feature of an application. It's an
optimization you do for code size. That is, there should not be an architectural
feature in the router to directly specifically control whether to lazy load something or
not based on conditions such as authentication. This slightly
different from the `canMatch` guard: the guard controls whether
you can use the route at all and as a side-effect, whether we download the code.
`CanLoad` only specified whether the code should be downloaded so `canMatch` is
more powerful and more appropriate.
* The naming of `CanLoad` will be potentially misunderstood for the `loadComponent` feature.
Because it applies to `loadChildren`, it feels reasonable to think that it will
also apply to `loadComponent`. This isn’t the case: since we don't need
to load the component until right before activation, we defer the
loading until all guards/resolvers have run.
* Unnecessary API surface bloat where two features (CanMatch and CanLoad) do
essentially the same thing. This affects code size for supporting two
nearly identical features as well as the learning and teaching journey
for them both.
* `CanLoad` guards have the downside of _only_ being run once to prevent
loading child routes. Once that passes and children are loaded, the
guard never runs again. As a result, developers need to always provide
_both_ canLoad and a canActivate in case the answer to the guard flips
back to `false`. This is not the case for `canMatch`, which will run
on every navigation.
DEPRECATED: CanLoad guards in the Router are deprecated. Use CanMatch
instead.
PR Close#48180
The router providers a configurable `onSameUrlNavigation` value that
allows developers to configure whether navigations to the same URL as
the current one should be processed or ignored. However, this only acts
as a default value and there isn't an API for easily overriding this for
a single navigation. Instead, developers are forced to update the value
of the property on the router instance and remember to reset it.
This feature fills a small gap in the Router APIs that enables
developers to accomplish the task of force reloading a bit easier.
Lengthy discussion about this here: #21115
PR Close#48050
This commit extracts the Router's navigation "transitions" to a separate
file. The goal here is twofold:
- Separate the Router's logic into more manageable chunks. Rather than
having to always edit a 1000+ line file, this separates different
pieces into smaller, more focused files
- More importantly, this sets the groundwork for separating the Router
state from the individual navigation transition. That is, it would be
good for the rxjs pipeline to _not_ modify the Router state but only
keep track of its own intermediate stages and emit outwards during
important events. The Router can subscribe to those events and make
updates to its state. This would theoretically allow us to swap those
implementations independently. That is, the Router's state management
can be changed without changing the transition handling and
vice-versa.
PR Close#48092