This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.
fixes#53369
BREAKING CHANGE: Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
PR Close#54265
Returning `UrlTree` from a guard was a convenient new feature added to
the `Router`. However, it does not have feature-parity with the old
`router.navigate(...); return false;` pattern. The most common use-case
for this feature is to redirect to a new page _without_ updating the URL
from the initially attempted navigation. For example, rendering a 404
page when the user does not have access privelages to a route.
Fixes#17004Fixes#27148
BREAKING CHANGE: Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
PR Close#45023
`RouterTestingModule` is not needed as of v16. Instead, TestBed
automatically provides `MockPlatformLocation` in order to help test
navigations in the application. The location mocks in the
RouterTestingModule aren't necessary anymore.
There doesn't appear to be any real documentation around
`RouterTestingModule` other than the API docs.
PR Close#49427
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
The current Router APIs require guards/resolvers to be present in the DI tree. This is because we want to treat all guards/resolvers equally and some may require dependencies. This requirement results in quite a lot of boilerplate for guards. Here are two examples:
```
const MY_GUARD = new InjectionToken<any>('my_guard');
…
providers: {provide: MY_GUARD, useValue: () => window.someGlobalState}
…
const route = {path: 'somePath', canActivate: [MY_GUARD]}
```
```
@Injectable({providedIn: 'root'})
export class MyGuardWithDependency {
constructor(private myDep: MyDependency) {}
canActivate() {
return myDep.canActivate();
}
}
…
const route = {path: 'somePath', canActivate: [MyGuardWithDependency]}
```
Notice that even when we want to write a simple guard that has no dependencies as in the first example, we still have to write either an InjectionToken or an Injectable class.
With this commit router guards and resolvers can be plain old functions.
For example:
```
const route = {path: 'somePath', component: EditCmp, canDeactivate: [(component: EditCmp) => !component.hasUnsavedChanges]}
```
Additionally, these functions can still use Angular DI with `inject` from `@angular/core`.
```
const route = {path: 'somePath', canActivate: [() => inject(MyDependency).canActivate()]}
```
PR Close#46684
Fixes all TypeScript failures caused by enabling the `--strict`
flag for test source files. We also want to enable the strict
options for tests as the strictness enforcement improves the
overall codehealth, unveiled common issues and additionally it
allows us to enable `strict` in the `tsconfig.json` that is picked
up by IDE's.
PR Close#30993
* Removed `andObservable` helper function in favor of inline implementation
* Flow `boolean | UrlTree` through guards check
* Add tests to verify behavior of `checkGuards` function flowing `UrlTree` properly
PR Close#26521
With these changes, the types are a little stricter now and also not
compatible with Protractor's jasmine-like syntax. So, we have to also
use `@types/jasminewd2` for e2e tests (but not for non-e2e tests).
I also had to "augment" `@types/jasminewd2`, because the latest
typings from [DefinitelyTyped][1] do not reflect the fact that the
`jasminewd2` version (v2.1.0) currently used by Protractor supports
passing a `done` callback to a spec.
[1]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/566e0394859fdc1dc893658ccec6b06372d56a91/types/jasminewd2/index.d.ts#L9-L15Fixes#23952Closes#24733
PR Close#19904
Previously, the router would merge path and matrix params, as well as
data/resolve, with special rules (only merging down when the route has
an empty path, or is component-less). This change adds an extra option
"paramsInheritanceStrategy" which, when set to 'always', makes child
routes unconditionally inherit params from parent routes.
Closes#20572.
* The problem was with the `fireChildActivationStart` function. It was taking a `path` param, which was an
array of `ActivatedRouteSnapshot`s. The function was being fired for each piece of the route that was being
activated. This resulted in far too many `ChildActivationStart` events being fired, and being fired on routes
that weren't actually getting activated. This change fires the event only for those routes that are actually
being activated.
fixes#18942
PR Close#19043