828 Commits

Author SHA1 Message Date
Andrew Scott 0a9d1060b9 refactor(router): Do not access browserPageId if not computed resolution (#49850)
This commit avoids accessing the routerPageId if the
canceldNavigationResolution is not computed.

PR Close #49850
2023-04-17 14:47:16 +00:00
Andrew Scott 09a42d988e fix(router): canceledNavigationResolution: 'computed' with redirects to the current URL (#49793)
The `canceledNavigationResolution: 'computed'` option does not correctly
assign page IDs or restore them when redirects result in navigating to
the current URL. This change ensures that the page IDs are still
incremented and restored correctly in this scenario.

PR Close #49793
2023-04-14 14:55:06 +00:00
Andrew Scott cad7274ef9 fix(router): create correct URL relative to path with empty child (#49691)
The previous fix for squashing empty children didn't quite work when the
existing route had segments. The result would be that the segments from
the existing route were dropped from the final URL.

PR Close #49691
2023-04-04 15:05:42 -07:00
Andrew Scott 9b61379096 fix(router): Ensure initial navigation clears current navigation when blocking (#49572)
The navigation transition clears the current navigation in the finalize
operator of the current navigation Observer. This commit both completes
the `bootstrapDone` observable and updates the transition to only take 1
emit from the completed navigation. Either of these changes on their own
would fix the issue. The latter is a preventative measure in case a
mistake like the former is made again.

fixes #49567

PR Close #49572
2023-03-31 17:04:02 -07:00
Andrew Scott 978d37f324 fix(router): Ensure Router preloading works with lazy component and static children (#49571)
The preloading strategy did not handle a `loadComponent` on a route with
a static `children`. It only preloaded children if they were also
`loadChildren` or both were not lazy loaded.

fixes #49558

PR Close #49571
2023-03-24 10:41:11 -07:00
Jan Cabadaj a844435514 fix(router): fix #49457 outlet activating with old info (#49459)
Avoid activating outlet with old info if route was changed before outlet activated

PR Close #49459
2023-03-22 14:41:43 -07:00
Andrew Scott be2db59a55 refactor(router): Remove deprecated loadChildren file (#49504)
This file was used while migrations were happening internally. All code is now updated to the callback

PR Close #49504
2023-03-21 14:09:23 -07:00
Andrew Scott 9c57b656a1 refactor(router): Update router export location for deprecated interfaces (#49504)
Moving these exports to a separate file will allow easier local patches internally.

PR Close #49504
2023-03-21 14:09:22 -07:00
Matthieu Riegler 6d6b76c59f docs(router): Improving linking (#49203)
Add links to @see elements and suggest a more explicit alternative for the depreciation of `CanActivate`.

PR Close #49203
2023-02-28 08:24:11 -08:00
Iván Navarro 3062442728 fix(router): add error message when using loadComponent with a NgModule (#49164)
Add a more specific error message when defining a lazy-loaded route using
`loadComponent` and passing it a NgModule instead of a standalone component,
when the user should actually be using `loadChildren`.

PR Close #49164
2023-02-27 10:09:55 -08:00
Michael Ziluck d7835e4f1a docs(router): fix code block closing ticks (#49185)
PR Close #49185
2023-02-23 10:37:25 -08:00
Walid Bouguima cff84d00cf docs(router): canMatch route guard method signature update (#49140)
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
2023-02-21 13:23:08 -08:00
Andrew Scott e63fb8031a refactor(router): Remove warning for an invalid ActivatedRoute (#49117)
This warning was put in place to surface an error when developers use an ActivatedRoute
with an invalid structure in tests. However, there isn't a clear path to fixing it and
the tests continue to pass (ideally - that's what the recovery code is there for).
Rather than surfacing an error that developers would be confused by and likely ignore,
it would be better to not warn at all unless there is a clearer action to take to
resolve the issue.

resolves #49116

PR Close #49117
2023-02-16 15:53:29 -08:00
cexbrayat 84ad4d0391 docs: missing closing parenthesis in withNavigationErrorHandler() example (#49013)
PR Close #49013
2023-02-10 08:46:48 +01:00
cexbrayat a28cf2438b docs(router): fix error handler deprecation (#49015)
The deprecation mentions `withErrorHandler` whereas the feature is called `withNavigationErrorHandler` since 15eccef4eb.

PR Close #49015
2023-02-10 08:41:55 +01:00
Andrew Scott 5128ba036a refactor(router): Warn if a navigation will change in the upcoming v16 release (#48688)
v16 will have a breaking change to the way `UrlTree`s are constructed.
This change is actually a bug fix that makes `UrlTree` creation correct
in more scenarios (see #48508). However, this can affect applications that are
relying on the current incorrect behavior. This commit adds a dev mode
warning when the target of a navigation will change once #48508 is
submitted.

PR Close #48688
2023-02-07 12:25:59 -08:00
Andrew Scott f5a7e02529 docs(router): Update functional guard and resolver docs (#48873)
This commit updates the docs of the functional guards and resolvers to improve the migration
experience when moving away from class-based equivalents.

PR Close #48873
2023-02-02 13:39:32 -08:00
Matthieu Riegler 16ef770db8 fix(router): Handle routerLink directive on svg anchors. (#48857)
On svgs, the tagNames are lowercase even for non-svg related tags like `a`.

fixes #48854

PR Close #48857
2023-02-02 09:38:06 -08:00
Andrew Scott dedac8d3f7 feat(router): Add test helper for trigger navigations in tests (#48552)
In order to test components and services which depend on router navigations, such as `ActivatedRoute` instances, tests currently need to provide a fair bit of boilerplate _or_ they can set up a stub for `ActivatedRoute` and list it in the `providers` to override it in `TestBed`. This approach of stubbing the `ActivatedRoute` creates a situation that can easily cause the test to break. The stub often only mocks out the dependencies that the component/service _currently_ needs. This dependencies might change over time and break the test in an unexpected way. In addition, it is difficult to get the structure of `ActivatedRoute` exactly correct.

This change will allow unit tests to quickly set up routes, trigger real navigations in the Router, and get instances of component's to test along with real instances of `ActivatedRoute`. This all comes without needing to know that the component depends on `ActivatedRoute` at all. This becomes more important when considering that a component may be refactored in the future to use `@Input` rather than access data on the `ActivatedRoute` instance (see #18967). Tests which mock out `ActivatedRoute` would all break, but those which use `navigateForTest` would continue to work without needing any updates.

resolves #15779
resolves #48608

PR Close #48552
2023-01-25 19:31:38 +00:00
Andrew Scott 930020c578 refactor(router): Move afterNextNavigation helper function to a reusable location (#48552)
There may be use-cases in the future where `afterNextNavigation` is used
in other locations. For example, a test helper function which navigates
should likely wait for all redirects to complete rather than simply
waiting for the promise returned from `navigate` to resolve.

PR Close #48552
2023-01-25 19:31:38 +00:00
Andrew Scott 4dcab333ae fix(router): 'createUrlTreeFromSnapshot' with empty paths and named outlets (#48734)
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
2023-01-18 10:46:43 -08:00
Andrew Scott b5137d82cc test(router): update createUrlTree tests to not use mocks (#48734)
The mocks in the tests make them hard to understand and they don't always test real router behavior

PR Close #48734
2023-01-18 10:46:43 -08:00
ced 5bb1223737 refactor(router): remove unused parameter in navigation internal function (#48724)
The internal `cancelNavigationTransition` required an unused `router` parameter.

PR Close #48724
2023-01-13 10:37:25 -08:00
Andrew Scott 926c35f4ac docs: Deprecate class and InjectionToken and resolvers (#47924)
Class and `InjectionToken`-based guards and resolvers are not as configurable,
are less re-usable, require more boilerplate, cannot be defined inline with the route,
and require more in-depth knowledge of Angular features (`Injectable`/providers).
In short, they're less powerful and more cumbersome.

In addition, continued support increases the API surface which in turn increases
bundle size, code complexity, the learning curve and API surface to teach,
maintenance cost, and cognitive load (needing to grok several different types
of information in a single place).

Lastly, supporting only the `CanXFn` types for guards and `ResolveFn` type
for resolvers in the `Route` interface will enable better code
completion and integration with TypeScript. For example, when writing an
inline functional resolver today, the function is typed as `any` and
does not provide completions for the `ResolveFn` parameters. By
restricting the type to only `ResolveFn`, in the example below
TypeScript would be able to correctly identify the `route` parameter as
`ActivatedRouteSnapshot` and when authoring the inline route, the
language service would be able to autocomplete the function parameters.

```
const userRoute: Route = {
  path: 'user/:id',
  resolve: {
    "user": (route) => inject(UserService).getUser(route.params['id']);
  }
};
```

Importantly, this deprecation only affects the support for class and
`InjectionToken` guards at the `Route` definition. `Injectable` classes
and `InjectionToken` providers are _not_ being deprecated in the general
sense. Functional guards are robust enough to even support the existing
class-based guards through a transform:

```
function mapToCanMatch(providers: Array<Type<{canMatch: CanMatchFn}>>): CanMatchFn[] {
  return providers.map(provider => (...params) => inject(provider).canMatch(...params));
}
const route = {
  path: 'admin',
  canMatch: mapToCanMatch([AdminGuard]),
};
```

With regards to tests, because of the ability to map `Injectable`
classes to guard functions as outlined above, nothing _needs_ to change
if projects prefer testing guards the way they do today. Functional
guards can also be written in a way that's either testable with
`runInContext` or by passing mock implementations of dependencies.
For example:

```
export function myGuardWithMockableDeps(
  dep1 = inject(MyService),
  dep2 = inject(MyService2),
  dep3 = inject(MyService3),
) { }

const route = {
  path: 'admin',
  canActivate: [() => myGuardWithMockableDeps()]
}

// test file
const guardResultWithMockDeps = myGuardWithMockableDeps(mockService1, mockService2, mockService3);
const guardResultWithRealDeps = TestBed.inject(EnvironmentInjector).runInContext(myGuardWithMockableDeps);
```

DEPRECATED: Class and `InjectionToken` guards and resolvers are
deprecated. Instead, write guards as plain JavaScript functions and
inject dependencies with `inject` from `@angular/core`.

PR Close #47924
2023-01-11 15:01:08 -08:00
Andrew Scott a3a4ca0b00 refactor(router): move internal router properties to transition handler where appropriate (#48475)
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
2023-01-10 07:59:16 -08:00
Andrew Scott cb6d73a84e fix(router): page refresh should not destroy history state (#48540)
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
2023-01-05 14:50:53 -08:00
Andrew Scott 15eccef4eb docs(router): Clean up error handler deprecations (#48551)
`errorHandler` and `malformedUriErrorHandler` were already deprecated in
the Router class public API. This change updates the deprecation to
extend to `RouterModule.forRoot` configuration options.

PR Close #48551
2023-01-05 14:49:00 -08:00
Andrew Scott 31b94c762f feat(router): Add a withNavigationErrorHandler feature to provideRouter (#48551)
`withNavigationErrorHandler` is a close replacement for the
`RouterModule.forRoot.errorHandler` / `Router.errorHandler`.
It provides a quick, short way for users to define a function to handle
`NavigationError` events.

PR Close #48551
2023-01-05 14:49:00 -08:00
Andrew Scott 0c5db1a26e refactor(router): Remove files no longer in use (#48500)
These files exist to support internal patches that are no longer needed

PR Close #48500
2023-01-05 14:42:27 -08:00
ced 2d3c98ddf3 docs: missing closing parenthesis in withHashLocation() example (#48507)
PR Close #48507
2023-01-04 12:26:21 -08:00
Paul Gschwendtner 3d6cdd6aaa refactor: update packages/router tests to be compatible with ESM (#48521)
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
2022-12-19 19:50:43 +00:00
Paul Gschwendtner c9415e4d75 build: ensure bootstrap transitive runfiles are made available (#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
2022-12-19 19:50:41 +00:00
Paul Gschwendtner 20551503fa build: replace _es2015 shorthand with more flexible _files suffix (#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
2022-12-19 19:50:41 +00:00
Andrew Scott 81203c6ec1 refactor(router): Add opt-in provider for upcoming router change (#47988)
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
2022-12-13 16:57:46 -08:00
Andrew Scott f58ad86e51 feat(router): Add feature provider for enabling hash navigation (#48301)
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
2022-12-13 08:28:38 -08:00
Andrew Scott caa1ad000e docs(router): Update ROUTES docs to not point to provideRoutes (#48417)
provideRoutes is deprecated in favor of the ROUTES token directly
for complex situations where it's necessary.

fixes #48411

PR Close #48417
2022-12-12 09:36:38 -08:00
Matthieu Riegler 0fa70dfb6d refactor(router): code cleaning (#48259)
Removing unnecessary type assertions, null assertions etc.

PR Close #48259
2022-12-09 09:59:20 -08:00
Matthieu Riegler 38421578a2 feat(core): Make the isStandalone() function available in public API (#48114)
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
2022-12-01 13:21:21 -08:00
Andrew Scott 80297348e8 refactor(router): Remove assignExtraOptionsToRouter helper function (#48215)
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
2022-12-01 09:38:26 -08:00
Andrew Scott a0551ee761 refactor(router): Eliminate constructor parameters in Router class (#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
2022-12-01 09:38:26 -08:00
Andrew Scott d5aaf5523d refactor(router): Remove DeprecatedLoadChildren (#48292)
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
2022-11-30 08:29:11 -08:00
Andrew Scott 0ff5d972cd refactor(router): Move navigationId handling to the transition manager (#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
2022-11-29 14:55:25 -08:00
Andrew Scott 55ae4aa234 refactor(router): Move transition subject into transition handler (#48202)
The navigation transitions subject belongs in the navigation transitions handler
rather than the Router.

PR Close #48202
2022-11-29 14:55:25 -08:00
Andrew Scott edd5192264 refactor(router): directly inject internal properties from DI (#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
2022-11-29 14:55:25 -08:00
Andrew Scott 17b76998ae refactor(router): Get EnvironmentInjector directly in transition handler (#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
2022-11-29 14:55:25 -08:00
Andrew Scott 7b1d63e939 refactor(router): Move configLoader to transition handler (#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
2022-11-29 14:55:25 -08:00
Andrew Scott 6810a04143 refactor(router): Move events subject to transition class (#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
2022-11-29 14:55:25 -08:00
Andrew Scott b02df19934 refactor(router): remove malformedUriHandler from interface passed to transitions (#48202)
The malformedUriHandler is not used during the navigation transition and can be removed form the interface

PR Close #48202
2022-11-29 14:55:25 -08:00
Andrew Scott aa66f703d2 Revert "refactor(router): remove malformedUriHandler from interface passed to transitions (#48202)" (#48269)
This reverts commit 17aba7c4c0.

PR Close #48269
2022-11-28 16:52:08 -08:00
Andrew Scott db1c73c431 Revert "refactor(router): Move events subject to transition class (#48202)" (#48269)
This reverts commit f555050f9a.

PR Close #48269
2022-11-28 16:52:07 -08:00