Use of the `SpyLocation` is problematic because it prevents location
APIs from reaching the platform level (`PlatformLocation`) and
`PathLocationStrategy`. This makes it difficult to test interactions
with those providers, including the ability to use the `Navigation` API,
which will live at the platform level.
PR Close#53640
The InitialRenderPendingTasks currently attempts to only contribute to
ApplicationRef stableness one time to support SSR. This isn't actually
how the switchMap works in reality. This commit updates
the isStable observable to be more clear that it's always a combination
of the zone stableness and pending tasks.
In addition, this commit renames the service to just be PendingTasks
because it doesn't directly relate to rendering. While the purpose is
to track things that might cause rendering to happen, we don't know if the
tasks will affect rendering at all.
PR Close#53534
The version of rxjs used to build the repository has been updated to v7.
This required only minimal changes to the code. Most of which were type
related only due to more strict types in v7. The behavior in those cases
was left intact. The most common type related change was to handle the
possibility of `undefined` with `toPromise` which was always possible with
v6 but the types did not reflect the runtime behavior. The one change that
was not type related was to provide a parameter value to the `defaultIfEmpty`
operator. It no longer defaults to a value of `null` if no default is provided.
To provide the same behavior the value of `null` is now passed to the operator.
PR Close#53621
Prior to this commit when a route is not matched and the application was running in production mode an `[Error]: NG04002` was logged in the console. This however, is not actionable when the application is running on the server where there can be multiple pages being rendered at the same time.
Now we change this to also log the route example: `[Error]: NG04002: 'products/Jeep'`.
Closes#53522
PR Close#53523
The `RouterTestingHarness` should throw an error if the call to `navigateByUrl`
expects a component to be activated but the navigation failed.
fixes#52344
PR Close#52357
The current way of computing a route's params and data recomputes
inherited data from the inheritance root every time. When the
inheritance strategy is "emptyOnly", this isn't necessarily the root of
the tree, but some point along the way (it stops once it reaches an
ancestor route with a component).
Instead, this commit updates parameter inheritance to only inherit data
directly from the parent route (again, instead of recomputing all
inherited data back to the inheritance root). The only requirement for
making this work is that the parent route data has already calculated
and updated its own inherited data. This was really already a
requirement -- parents need to be processed before children.
In addition, the update to the inheritance algorithm in this commit
requires more of an understanding that a resolver running higher up in
the tree has to propagate inherited data downwards. The previous
algorithm hid this knowledge because resolvers would recompute inherited
data from the root when run. However, routes that did not have resolvers
rerun or never had resolvers at all would not get the updated resolved data.
fixes#51934
PR Close#52167
DEPRECATED: NgProbeToken
The `NgProbeToken` is not used internally since the transition from View Engine to Ivy. The token has no utility and can be removed from applications and libraries.
PR Close#51396
This adds `generate_api_docs` targets to all of the packages for which we publish api reference docs. One known issue here is that any type information that comes from another package (e.g. router depending on core) currently resolve to `any` because the other sources are not available in the program. This can be tackled in a follow-up commit.
This commit also updates the install patch for `@angular/build-tools` to use the local version of compiler-cli.
PR Close#52034
A new flag added to the component's debug info to determine whether to throw runtime error (in dev mode) if component is being rendered without its NgModule. This flag is only set for non-standalone components.
PR Close#52061
This commit adds the ability to provide a function that will get called
immediately after the view transition is created. This will allow
developers to do things like add/remove classes from the DOM when the
transition animation is finished, skip the transition based on
application conditions, etc. Having access to the transition unlocks
just about every example outlined in https://developer.chrome.com/docs/web-platform/view-transitions.
Note that the timing of the `updateCallback` execution is in the spec as
being called asyncronously (https://drafts.csswg.org/css-view-transitions-1/#callbackdef-updatecallback).
This means the `onViewTransitionCreated` callback is guaranteed to
execute before the update callback which in turn means it is guaranteed
to execute before the view transition `ready`/animation. As a result, it
is safe/effictive to add classes to the document in the
`onViewTransitionCreated` function in order to control animations of
that transition and then remove those classes in the transition's `finished`
`Promise`. The animation also doesn't start until the `Promise` returned
by `updateCallback` resolves, so this would also guarantee that the
animation starts asynchronously.
resolves#51827
PR Close#52002
When a route has loadComponent, its children should not inherit params and
data unless paramsInheritanceStrategy is 'always'.
fixes#52106
BREAKING CHANGE: Routes with `loadComponent` would incorrectly cause
child routes to inherit their data by default. The default
`paramsInheritanceStrategy` is `emptyOnly`. If parent data should be
inherited in child routes, this should be manually set to `always`.
PR Close#52114
The router currently restricts all further redirects after an absolute
redirect. Because there's no documented reason for _why_ this
restriction is in place, I'm now deeming this unnecessary. Developers
should not be restricted in this manner. Instead, configs that may
have caused infinite redirects in the past should be updated to not be
infinite. It is confusing to ignore configs with redirects after an
absolute redirect occurred because it creates different matching rules
depending on the whether an absolute redirect has happened or not.
For additional context on why I believe removing this restriction is
necessary, #13373 asks for allowing `redirectTo` to be a function. It
would make sense to allow this function to return a `UrlTree` like other
guards in the Router. When guards in the `Router` return `UrlTree`, they
cancel the current navigation and start a new one to re-do the route
matching. Since we're already in the router matching part, we don't need
to cancel the navigation. However, the restriction on absolute redirects
here then creates a weird situation where developers wouldn't see any
other redirects if they returned a `UrlTree` as an absolute redirect
from `redirectTo`.
resolves#39770
BREAKING CHANGE: Absolute redirects no longer prevent further redirects.
Route configurations may need to be adjusted to prevent infinite
redirects where additional redirects were previously ignored after an
absolute redirect occurred.
PR Close#51731
The `Writable` type is usefull when we want overwrite readonly properties and we still want to maintain code navigation/reference. It should be use instead of `any` type assertions for example.
PR Close#49754
This commit adds an option to the view transition feature to skip the first transition.
This option is not available in RouterModule.forRoot.
resolves#51815
PR Close#51825
The `setupTestingRouter` function is a factory function for creating a
new instance of the `Router`. This function is effectively a no-op.
Developers should use `RouterModule.forRoot` or `provideRouter` in tests
instead.
BREAKING CHANGE: The `setupTestingRouter` function has been removed. Use
`RouterModule.forRoot` or `provideRouter` to setup the `Router` for
tests instead.
PR Close#51826
This commit refactors the loadChildren callback execution of the router config loader
into a function that can be used with SSR for the purposes of route extraction.
PR Close#51818
The browserUrlTree is only used to support the onSameUrlNavigation: 'ignore' logic. We can achieve this functionality without having this state tracked inside the Router. Instead, we can re-examine what ignore means: We don't want to rerun the matching logic, guards, or resolvers when we already know that nothing is changing.
Outside of the "navigated", there are two things that constitute a "change":
1. The browser URL might change. Because of skipLocationChange, the browser URL might not always match the internal state of the Router (we can navigate to a path but skip updating the browser URL). If we're navigating to a place that would change the browser URL, we should process the navigation. Theoretically, all we need to really do is update the browser URL instead of processing the whole navigation w/ guards, redirects, and resolvers. But this doesn't matter that much because the default value for runGuardsAndResolvers will skip all of this anyways.
2. The internal state of the Router might change. That is, we're navigating to a new path and may or may not be updating the updating the browser URL.
If either of the above are true, we process the navigation. If both are false, we aren't changing anything so we can safely ignore the navigation request (as long as onSameUrlNavigation === 'ignore').
Why is this change important?
* Simplification of Router internals. The Router has a lot of special case handling and one-offs to handle a limited set of scenarios. Removing these when possible makes the code easier to follow
PR Close#48065
The `malformedUriErrorHandler` is used as a recovery mechanism for when the `UrlSerializer`
throws an error when parsing a URL string. If custom error handling is
desired for this, it should instead be done inside the
`UrlSerializer.parse` method itself. There's no reason to have an entire
feature option built around what can otherwise just be `try...catch`.
BREAKING CHANGE: `malformedUriErrorHandler` is no longer available in
the `RouterModule.forRoot` options. URL parsing errors should instead be
handled in the `UrlSerializer.parse` method.
PR Close#51745
Terser does not treat `Symbol` as side-effect free- so if we end up with
a symbol export being loaded, it will result in the symbol being
retained.
We noticed this in the signals prototyping where symbols exported
from `computed` ended up appearing in symbol bundling tests.
PR Close#51776
BREAKING CHANGE: Node.js v16 support has been removed and the minimum support version has been bumped to 18.13.0.
Node.js v16 is planned to be End-of-Life on 2023-09-11. Angular will stop supporting Node.js v16 in Angular v17. For Node.js release schedule details, please see: https://github.com/nodejs/release#release-schedule
PR Close#51755
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.
PR Close#51728
The View Transitions API enables easy animations when transitioning between different DOM states. This commit adds an opt-in feature to the Router which runs the component activation and deactivation logic in the document.startViewTransition callback. If the browser does not support this API, route activation and deactivation will happen synchronously.
resolves#49401
PR Close#51314
For redirects, most of the logic between wildcard and regular redirects
is identical. Combine what can be combined there. Once that was done,
the first part of the matching for redirects looks almost identical to the regular
matching. Create helpers and combine simplify code where possible there
as well.
PR Close#51543
This commit updates the return types of the matching functions to only
return an array when more than one return value is actually possible.
PR Close#51543
This commit removes the `urlHandlingStrategy` from the public Router's API
BREAKING CHANGE:
`urlHandlingStrategy` has been removed from the Router public API.
This should instead be configured through the provideRouter or RouterModule.forRoot APIs.
PR Close#51631
This commit refactors the router internals to track state inside a separate
`StateManager`. This helps open the door to managing the state in
different, swappable providers. The current interface needed by the
Router is: `currentUrlTree`, `rawUrlTree`, `browserUrlTree`,
`routerState`, and `handleNavigationEvent` (other properties are because
some router properties are writeable when they shouldn't be). This is
a suprisingly small interface and can hopefully be made smaller in the
future (i.e. removing 1 or more of the 3 tracked of `UrlTree`s).
PR Close#48481
The data `Observable` is not updated unless there have been changes to
the object. The current diffing does not look at `symbol` keys of the
object but the `title` property is stored as a private `symbol`. This
commit updates the object diffing to include symbols.
fixes#51401
PR Close#51561
This commit removes deprecated properties on the Router. These are meant
to be configured through DI and not meant to be changed during runtime.
BREAKING CHANGE: The following Router properties have been removed from
the public API:
- canceledNavigationResolution
- paramsInheritanceStrategy
- titleStrategy
- urlUpdateStrategy
- malformedUriErrorHandler
These should instead be configured through the `provideRouter` or
`RouterModule.forRoot` APIs.
PR Close#51502
Rather than the navigation transitions managing Router state, this
commit updates the Router to manage its own state based on ongoing
transition events. In the future, this can be abstracted even further to
have a totally separate class that manages the Router state. This would
allow the potential for swapping state manager implementations rather
than having to implement all types of state management in a single place.
One finding during tests was that unexpected errors thrown by the state management code moved
to the Router here will no longer be caught by the transition pipe's `catchError`.
This only includes calls to the following public Api methods:
* `go`, `replaceState`, `historyGo`, `isCurrentPathEqualTo` on `Location`
* `UrlSerializer.serialize`
* `UrlHandlingStrategy.merge`.
None of these methods should throw if the router is expected to function.
These might throw when tests include incomplete mocks, which is not
supported, or in cases where the actual browser methods like
`replaceState` would throw. This will already result in unexpected/unsupported
behavior. The failure case here is now arguably better - the navigation
itself still completes but the state update (either updating Router
internal state or updating the browser URL) fails separately and is
unhandled.
PR Close#48427