Fix initializer of instance members that reference identifiers declared in
the constructor.
When public class fields are enabled, such cases throw TS2729: property used
before its initialization.
PR Close#58349
Angular DevTools uses globally available functions to provide debugging information to the framework. This commit exports `getLoadedRoutes` function using the `ɵpublishExternalGlobalUtil` function added in PR: f5cd8f7ab4.
Follow-up PRs that will:
- Add a new router example in the Angulat DevTools demo application.
- Implement the router graph in the Angular DevTools to view the routes that are loaded in the application
PR Close#58199
In order to investigate the performances of SSR, this commit introduces a benchmark suite which will measure several step of the rendering.
PR Close#57647
Nothing of concern arose during the time this feature was in the
experimental phase. There are no plans to change the shape of the API.
This change also updates the route animations documentation to use the
view transitions feature instead of the old and difficult to follow
guide that used the animations package. The content was taken from the
blog post: https://blog.angular.io/check-out-angulars-support-for-the-view-transitions-api-3937376cfc19
PR Close#55600
This change aligns the behavior of the error handler in the
`ExtraOptions` of `RouterModule.forRoot` with the error handler in
`withNavigationErrorHandler`. The changes are:
* Slightly different timing: The handler is called before the
`NavigationError` emits
* Runs in the injection context, meaning it is more configurable at the
config location rather than needing to assign the value to the
`Router.errorHandler` later to get access to injectables
* Can now return `RedirectCommand` to recover from the error and
redirect without emitting `NavigationError`
* No longer allows arbitrarily overriding return value of the navigation
promise
BREAKING CHANGE: The `Router.errorHandler` property has been removed.
Adding an error handler should be configured in either
`withNavigationErrorHandler` with `provideRouter` or the `errorHandler`
property in the extra options of `RouterModule.forRoot`. In addition,
the error handler cannot be used to change the return value of the
router navigation promise or prevent it from rejecting. Instead, if you
want to prevent the promise from rejecting, use `resolveNavigationPromiseOnError`.
PR Close#57050
This commit updates the interface of `Resolve` to allow for
`RedirectCommand`, as was done with `ResolveFn` in v18.
fixes#57131
BREAKING CHANGE: The return type of the `Resolve` interface now includes
`RedirectCommand`.
PR Close#57309
This commit adds an input to `RouterOutlet` that allows developers to
pass data from a parent component to the outlet components.
Setting the `routerOutletData` input on `RouterOutlet` makes the value
available to the child component injectors via the `ROUTER_OUTLET_DATA`
token. This token uses a `Signal` type to allow updating the input value
and propogating it to the token rather than needing to make the value
static.
resolves#46283
PR Close#57051
This commit adds an option to specify the default value for
`queryParamsHandling` in `Router.createUrlTree` when another option is
not specified (or is `null|undefined`).
resolves#12664
PR Close#57198
This commit allows configuring `NgZone` through the providers for
`bootstrapModule`. Prior to this change, developers had to configure
`NgZone` in the `BootstrapOptions`.
PR Close#57060
To increase the ease of development we are moving @angular/docs into the adev directory within this repo. While
we are doing this to improve our development experience in the short term, efforts are also in place
to maintain a division between this @angular/docs (shared) code and adev itself, so that it can be extracted
back out in the future when components is ready to leverage it as well.
PR Close#57132
This reverts commit 66ffeca2de.
It looks like nuxt encountered the same issue with scrolling when
waiting for Vue's `nextTick`, which is a microtask. This would have
similar timing to ZoneJS's rendering in the microtask queue. This
reverts to a `setTimeout` alone, though recreates the problem in #53985.
This was also mentioned in one of the comments in the Nuxt issue and the
solution would be `rAF`.
In order to address #53985, we'd likely want to use the `race(rAF, setTimeout)`
that we use in the zoneless and coalescing schedulers. This would have effectively the same timing as
the `afterNextRender` implementation here with zoneless, but quite
different timing to `afterNextRender` with ZoneJS.
fixes#57109
PR Close#57115
This commit delays makes two changes:
* Use the `read` phase for `afterNextRender` hook. We really want to
wait for any write hooks to complete before starting the animation
* In addition, wait a macrotask before resolve (really, this makes the
above change unnecessary but it's still conceptually the right
thing). This ensures any follow-up rendering in the microtask queue
is flushed before the animation starts.
Important note: This only affects the timing of the animation start,
delaying it longer to allow additional rendering/change detections to
flush. This promise already resolves in an `afterNextRender` hook and is
only used directly by the browser's view transition machinery.
PR Close#56494
Many developers find these interfaces useful for various reasons. Beyond
that, the deprecation of the interfaces has incorrectly implied that
existing class-based guard implementations need to be migrated to
functions. Class injectables are _not_ deprecated and choosing to
implement a guard's state and logic as a class that is injectable in the
functions run inside the injection context is valid.
resolves#50234
PR Close#56408
This feature adds a property to the `NavigationBehaviorOptions` that
allows developers to define a different path for the browser's address
bar than the one used to match routes. This is useful for redirects
where you want to keep the browser bar the same as the original
attempted navigation but redirect to a different page, such as a 404 or
error page.
fixes#17004
PR Close#53318
This parameter was removed in a recent change but is being added back to
avoid breaking code in a minor version.
While the changes parameter is not used, some code relies on it, mostly
through API misuse (extending `RouterLink`, manually calling `ngOnChanges`, etc.).
PR Close#56371
This commit adds `UrlTree` as a valid input to `routerLink`. It
disallows using this together with any inputs that come from
`UrlCreationOptions`, such as `queryParams` or `fragment`.
We could, in the future, decide on a different approach for these, like merging or
replacing those in `urlTree` input. We cannot, however, go the other way
(decide to prevent those inputs if we've already decided to allow it and
using a merging/replacing strategy). For this reason, an error seems the
most reasonable approach to start and we can re-evaluate if there's a
compelling reason to.
fixes#34468
PR Close#56265
Related to #51131, this change ensures that the router navigation exits
the current event loop before rendering the route when the view transition
feature is enabled, when the browser does not support view transitions.
PR Close#55327
Using `setTimeout` to delay scrolling can result in scrolling in the
next frame and cause noticeable flicker. This commit scrolls as soon as
the next render happens (or in `setTimeout` if a render does not happen
before then).
fixes#53985
PR Close#55105
`RouterOutlet` uses a unique injector logic that returns a value that correspond to the `ActivatedRoute` token dynamically. This logic breaks when a component/directive/pipe that injects the `ActivatedRoute` is located within a `@defer` block, because defer creates an `EnvironmentInjector` instance, which doesn't have that dynamic logic.
We've added some special handling of the `OutletInjector` in one of the previous commits, but it was incomplete and it was not covering cases when different routes use the same component. This commit updates defer logic to re-establish this dynamic behavior for `ActivatedRoute` by creating an instance of the `OutletInjector` when a parent injector was also an instance of `OutletInjector`.
This fix is a short-term solution and longer term we should find a way to achieve the dynamic behavior that Router relies on, but without adding a special case logic into defer.
Resolves#54864.
PR Close#55374
This commit adds the ability to return `RedirectCommand` from the error
handler provided by `withNavigationErrorHandler`. This will prevent the
error from being surfaced in the `events` observable of the Router and
instead convert the error to a redirect. This allows developers to
have more control over how the Router handles navigation errors. There
are some cases when the application _does not_ want the URL to be reset
when an error occurs.
resolves#42915
PR Close#55370
When Angular receives a clear indication that change detection should
run again, this should not be ignored, regardless of what Zone it
happened in. This change updates the default change detection scheduling
approach of Zone-based applications to ensure a change detection will
run when these events happen outside the Angular zone (which includes,
for example, updating a signal that's read in a template, setting an
input of a `ComponentRef`, attaching a view marked for check, calling
`ChangeDetectorRef.markForCheck`, etc.).
This does not apply to applications using `NoopNgZone` or those which
have a custom `NgZone` implementation without ZoneJS.
The impact of this change will most often be seen in existing unit tests. Tests
execute outside the Angular Zone and this can mean that state in the
test is not fully recognized by Angular. Now that Angular will ensure
change detection _does_ run, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior. Often, this should be seen
as more correct and the test should be updated, but in cases where it is
too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
fixes#55238fixes#53844fixes#53841fixes#52610fixes#53566fixes#52940fixes#51970fixes#51768fixes#50702fixes#50259fixes#50266fixes#50160fixes#49940fixes#49398fixes#48890fixes#48608fixes#45105fixes#42241fixes#41553fixes#37223fixes#37062fixes#35579fixes#31695fixes#24728fixes#23697fixes#19814fixes#13957fixes#11565fixes#15770fixes#15946fixes#18254fixes#19731fixes#20112fixes#22472fixes#23697fixes#24727fixes#47236
BREAKING CHANGE:
Angular will ensure change detection runs, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior.
This change will be more likely to impact existing unit tests.
This should usually be seen as more correct and the test should be updated,
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
Similarly, applications which may want to update state outside the zone
and _not_ trigger change detection can add
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the providers in `bootstrapApplication` or add
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
`BootstrapOptions` of `bootstrapModule`.
PR Close#55102
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 a `RedirectCommand` from a resolver can be interpreted as
distinctly different from regular resolved data. When a resolver returns
`RedirectCommand` we can interperet this as an intention to redirect in
the same way as other guards.
resolves#29089
PR Close#54556
This commit updates the internal resolve value of the navigation promise
to use `false` instead of `null` when a navigation is skipped. The
navigation promise type requires `boolean` so the correct resolution to
match the truthy/falsiness of the currently resolved value, `null`, is
`false` instead.
PR Close#55068
This commit moves the call to the error handler to the location where
the error event emits instead of having it indirectly work through the
events subscription. This change would also allow the handler to return
a value which can be handled by the navigation transition.
PR Close#55068
This commit fixes the types on the error handler resolve and reject
functions and also ensures that the resolve value matches the API type
(`boolean`, not "any random value returned from `errorHandler`"). This
could be considered a breaking change but I would argue instead that
relying on the return value of the error handler is API misuse because
the promise returned by the router navigation _does not_ include `any`
in its type.
PR Close#55068
This commit fixes the internal types for the resolve and reject
functions used for the router navigation Promise. These are currently
typed as `any`.
PR Close#55068