Commit graph

530 commits

Author SHA1 Message Date
Andrew Scott
7a2d029f51 refactor(router): Add provider for integrating with Navigation API and Location shim
This adds a (private) provider for integrating with the browser Navigation API.
This provider ensures that interactions with the `Location` service
use the underlying platform navigation rather than the history and
location APIs.

(cherry picked from commit dd09da8ba2)
2025-10-27 09:22:00 +01:00
Andrew Scott
b7cefeb864 fix(router): handle parenthesized outlets without a name in DefaultUrlSerializer (#64507)
Previously, the `DefaultUrlSerializer` would incorrectly parse URLs with a parenthesized outlet that did not have a name, such as `/(left)`. This would result in an `undefined` outlet name in the serialized URL.

This commit fixes the issue by ensuring that parenthesized outlets without a name are treated as primary outlets.

fixes #58516. Based on the description, either the URL was constructed
manually or by custom serializer.

PR Close #64507
2025-10-23 12:33:59 +02:00
Kristiyan Kostadinov
9d48e534e2 Revert "feat(router): allow router outlet to be set on ng-container (#64562)" (#64584)
This reverts commit 2bd764a3c4.

PR Close #64584
2025-10-22 16:35:38 +00:00
Kristiyan Kostadinov
2bd764a3c4 feat(router): allow router outlet to be set on ng-container (#64562)
Updates the selector for `RouterOutlet` to allow for it to be set on an `ng-container`. This allows it to not render the host node which can affect the layout.

Fixes #64553.

PR Close #64562
2025-10-21 16:49:06 +00:00
Andrew Scott
7afc193016 fix(router): Fix outlet serialization and parsing with no primary children (#64505)
this fixes tree creation, serialization, and parsing of trees created with
children outlets and no primary path

fixes #62384

PR Close #64505
2025-10-20 21:18:46 +00:00
Andrew Scott
f6a73f1913 fix(router): Respect custom UrlSerializer handling of query parameters (#64449)
Previously, query parameters passed to `router.createUrlTree` were simply converted to strings. This meant that any custom serialization logic in a custom `UrlSerializer` was not applied. This could lead to inconsistencies between navigations triggered from the URL bar (which are parsed by the serializer) and navigations triggered programmatically.

This change ensures that query parameters are normalized using the provided `UrlSerializer`. The values are serialized and then parsed to ensure they are in the same format as if they had come from a URL. This allows custom serializers to handle complex objects in query parameters consistently.

Fixes https://github.com/angular/angular/issues/47307

PR Close #64449
2025-10-20 18:42:56 +00:00
Andrew Scott
7fb7511124 fix(router): Surface parse errors in Router.parseUrl (#64503)
logs error in addition to fallback parse

fixes #54937

PR Close #64503
2025-10-20 17:51:29 +00:00
Jessica Janiuk
c60ab336c9 Revert "fix(router): Respect custom UrlSerializer handling of query parameters (#64449)" (#64511)
This reverts commit 46ae034c70.

PR Close #64511
2025-10-18 00:19:40 +00:00
Andrew Scott
46ae034c70 fix(router): Respect custom UrlSerializer handling of query parameters (#64449)
Previously, query parameters passed to `router.createUrlTree` were simply converted to strings. This meant that any custom serialization logic in a custom `UrlSerializer` was not applied. This could lead to inconsistencies between navigations triggered from the URL bar (which are parsed by the serializer) and navigations triggered programmatically.

This change ensures that query parameters are normalized using the provided `UrlSerializer`. The values are serialized and then parsed to ensure they are in the same format as if they had come from a URL. This allows custom serializers to handle complex objects in query parameters consistently.

Fixes https://github.com/angular/angular/issues/47307

PR Close #64449
2025-10-17 17:30:46 +00:00
Andrew Scott
2c85d2802f refactor(router): update route config loading to use async/await (#64322)
This simplifies code by using async/await instead of rxjs in the config
loading internals. While loadChildren/loadComponent could _technically_
return a synchronous value, the expectation is that this would be used
for dynamic imports, which are necessarily async.

PR Close #64322
2025-10-13 09:58:10 -07:00
Andrew Scott
e1da41ffdf fix(router): Scroll restoration should use instant scroll behavior for traversals (#64299)
When the scroll position is being restored, this change upates the
behavior to use 'instant' rather than the default 'auto', which will
be whatever the browser behavior is for 'window.scrollTo'. The 'smooth'
behavior does not match how browsers behavior when performing a
traversal navigation for MPAs, which is 'instant'.

related to #58258

PR Close #64299
2025-10-09 11:13:45 -07:00
Kristiyan Kostadinov
f5b50ec20d refactor: clean up explicit standalone flags from tests (#63963)
Since standalone is the default, we can dropn the `standalone: true` flags from our tests.

PR Close #63963
2025-09-22 14:27:34 +00:00
AleksanderBodurri
d006721f30 feat(devtools): clean up router tree for stable release (#63081)
Addresses some cleanup items for the router tree:

- No longer loads router ng global APIs as a side effect of importing the router. Rather this is now a runtime step that occurs when provideRouter is called.
- No longer depends on router.navigateByUrl in Angular DevTools. There is now a dedicated global util for this
- Router instance logic no longer depends on token name
- Prevents navigating to lazy or redirect routes (these don't have an associated component)

PR Close #63081
2025-09-02 20:59:15 -07:00
Andrew Scott
4c36659ba9 refactor(router): Add handling for empty observables in guards (#63546)
This fixes a bug introduced in #63485 where `firstValueFrom` was used. This
doesn't work in all situations here because some observables don't
emit before completing. These errors should result in the route matching
logic moving on to the next route.

Note: This is marked as a refactor rather than fix because the commit above is not in
any release yet.

PR Close #63546
2025-09-02 11:50:49 -07:00
Andrew Scott
bbb46e50d4 refactor(router): Add firstValueFrom helper (#63485)
This fixes a bug introduced in #62994 where `toPromise` was used. This
doesn't work in all situations here because some observables don't
complete. This only affected the redirect path, since the others are
already behind other rxjs code which takes the first value from the user
guards.

Note: This is marked as a refactor rather than fix because the commit above is not in
any release yet.

PR Close #63485
2025-08-29 19:02:04 +00:00
Andrew Scott
5b53535dd1 fix(router): Update recognize stage to use internally async/await (#62994)
This is effectively a revert of 72e6a948bb.
Debugging the recognize stage is considerably easier with async/await
stacks compared to rxjs. This also improves maintainability and is a
better 1:1 with server-side logic that has been implemented to match
and can be more easily kept in sync.

This also ensures that the recognize step is always async, whereas it
can sometimes be synchronous with rxjs.

BREAKING CHANGE: Router navigations may take several additional
microtasks to complete. Tests have been found to often be highly
dependent on the exact timing of navigation completions with respect to
the microtask queue. The most common fix for tests is to ensure all
navigations have been completed before making assertions. On rare
occasions, this can also affect production applications. This can be
caused by multiple subscriptions to router state throughout the application,
both of which trigger navigations that happened to not conflict with the
previous timing.

PR Close #62994
2025-08-29 08:55:13 -07:00
Joey Perrott
2fcafb65c5 build: rename defaults2.bzl to defaults.bzl (#63383)
Use defaults.bzl for the common macros

PR Close #63383
2025-08-25 15:45:01 -07:00
Matthieu Riegler
4e0fc81491 feat(router): convert lastSuccessfulNavigation to signal (#63057)
This commit also include an `ng update` migration to ensure `lastSuccessfulNavigation` is invoked.

BREAKING CHANGE: `lastSuccessfulNavigation` is now a signal and needs to be invoked

PR Close #63057
2025-08-13 11:29:01 -07:00
Matthieu Riegler
687c374826 feat(router): add a currentNavigation signal to the Router service. (#63011)
This new signal property is convenient to derive a `isNavigating` state.

`isNavigating = computed(() => !!this.router.currentNavigation())`

DEPRECATED: The Router.getCurrentNavigation method is deprecated. Use the Router.currentNavigation signal instead.

fixes #62958

PR Close #63011
2025-08-06 09:54:53 -07:00
Kristiyan Kostadinov
ddf779e18f Revert "feat(router): add a currentNavigation signal to the Router service. (#62971)" (#63010)
This reverts commit d00b3fed58.

PR Close #63010
2025-08-05 18:02:56 +02:00
Matthieu Riegler
d00b3fed58 feat(router): add a currentNavigation signal to the Router service. (#62971)
This new signal property is convenient to derive a `isNavigating` state.

`isNavigating = computed(() => !!this.router.currentNavigation())`

DEPRECATED: The Router.getCurrentNavigation method is deprecated. Use the Router.currentNavigation signal instead.

fixes #62958

PR Close #62971
2025-08-05 10:05:49 +02:00
Joey Perrott
cbc258eec8 build: remove ts_project_interop infrastructure (#62908)
Remove the interop macros and final usages

PR Close #62908
2025-07-31 09:12:58 +00:00
Andrew Scott
92b080202d test(router): Use autoTick feature in router tests (#62776)
This updates async router tests to use the jasmine autoTick feature. Observed test timings
for the chromium tests went down from ~7.5s to ~3.5-4s. For node, these decreased from ~5.5s to ~3s.

In addition to the speed improvement, this feature:

* Removes the need to be careful about timeout ordering when there are several timeouts in tests.
* Removes the need to ensure test timeouts are kept sufficiently small
* Reduces overall flakiness

PR Close #62776
2025-07-24 10:04:05 +00:00
Dmitrij Kuba
9c45c322d1 fix(router): ensure preloaded components are properly activated (#62502)
Preloaded components were not being activated in certain scenarios when preloading was enabled. This change ensures that components are correctly activated after being preloaded.

PR Close #62502
2025-07-09 14:39:39 -07:00
Joey Perrott
b84859073b build: migrate to use web test runner rules (#62292)
Migrate karma tests throughout the repo to use the new web test runner based rule instead

PR Close #62292
2025-06-26 17:19:10 +00:00
Andrew Scott
9833d9ea47 feat(router): Run loadComponent and loadChildren functions in the route's injection context (#62133)
This updates the loader code to run the `loadComponent` and
`loadChildren` functions in the appropriate injection context for the
route.

A primary motiviation for this feature is to bring `loadChildren` with
standalone components and the routes array to
feature-parity with what was possible when using `loadChildren` and a
module that provided routes via the `ROUTES` token and a factory
function (which would have injection context).

fixes #51532

PR Close #62133
2025-06-24 09:39:48 +00:00
Andrew Scott
c5fcb9d7f4 test(router): Add test for empty path redirect and no match (#62176)
this was discovered during some other work in the router that unintentionally changed this behavior

PR Close #62176
2025-06-23 14:18:12 +02:00
Andrew Scott
9cc7c5f38e test(router): Update timeouts to reduce firefox flakiness (#62141)
This updates the timeouts in a couple flakey router tests. Ideally we can use the jasmine
auto ticking as soon as tests are migrated to web test runner and we are on the latest
version of jasmine

PR Close #62141
2025-06-20 14:39:35 -07:00
Joey Perrott
3a0cfd544d build: migrate to using new jasmine_test (#62086)
Use the new jasmine_test based on rules_js instead of jasmine_node_test from rules_nodejs

PR Close #62086
2025-06-18 08:27:26 +02:00
Matthieu Riegler
dba912dd07 refactor(platform-browser): replace platform-browser-dynamic with platform-browser (#61498)
The former isn't needed anymore and is now deprecated.

PR Close #61498
2025-05-21 14:01:49 +00:00
Joey Perrott
3acc2a5f07 build: migrate router to use rules_js (#61542)
Use ts_project and ng_project for building router

PR Close #61542
2025-05-21 09:53:34 +00:00
Paul Gschwendtner
3a106a35bc build: move private testing helpers outside platform-browser/testing (#61472)
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.

This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.

PR Close #61472
2025-05-20 10:00:43 +00:00
Paul Gschwendtner
032b802f54 build: remove irrelevant madge circular deps tests (#61156)
We don't need this tooling anymore because we are already validating
that there are no circular dependencies via the `ng-dev` tooling that
checks `.ts` files directly.

Also these tests never actually failed to my knowledge.

PR Close #61156
2025-05-07 11:28:59 -07:00
Andrew Scott
55a0621cbd test(router): Reduce timeout times (#61155)
Router tests use real async so unnecessarily long timeouts are an issue

PR Close #61155
2025-05-07 11:16:26 -07:00
Andrew Scott
0c925af2dd test(router): This commit removes ZoneJS from the router tests (#61078)
There is nothing in the Router that requires ZoneJS and we do not need
`fakeAsync` as a mock clock. We can instead use any mock clock implementation
to speed up test execution.

This removes ZoneJS completely from the bundle of the Router tests.
ZoneJS causes the stacks to be unreadable when combined with the massive
rxjs stack in the router transition.

PR Close #61078
2025-05-05 08:55:01 -07:00
Andrew Scott
2e80744581 test(router): Fix slow-running infinite loop test and remove unnecessary duplicate tests (#61076)
The inifinite loop test is a real infinite loop and runs until a stack
overflow happens. In addition, all the promise and observable tests are
just duplicates of the other redirects and don't test any additional
logic. Instead, this change updates one test to return an observable and
another to return a promise

PR Close #61076
2025-04-30 14:18:09 -07:00
Andrew Scott
e8147df0e1 refactor(router): Move router integration suite to zoneless (#61046)
This commit moves the router integration tests to use zoneless

PR Close #61046
2025-04-29 21:56:01 -07:00
Andrew Scott
f36f2f2cb4 refactor(router): Remove inject helper from router tests (#61046)
This removes the `inject` helper from core/testing in the router tests.

PR Close #61046
2025-04-29 21:56:01 -07:00
Andrew Kushnir
c2987d8402 refactor(core): stop producing ng-reflect attributes by default (#60973)
BREAKING CHANGE:

This commit deprecates `ng-reflect-*` attributes and updates the runtime to stop producing them by default. Please refactor application and test code to avoid relying on `ng-reflect-*` attributes.

To enable a more seamless upgrade to v20, we've added the `provideNgReflectAttributes()` function (can be imported from the `@angular/core` package), which enables the mode in which Angular would be producing those attribites (in dev mode only). You can add the `provideNgReflectAttributes()` function to the list of providers within the bootstrap call.

PR Close #60973
2025-04-24 10:07:35 -07:00
MeddahAbdellah
62de7d930a feat(router): add asynchronous redirects (#60863)
Adds support for asynchronous redirects in the router, allowing redirect logic to be resolved dynamically (e.g., via API or async function). This enhances routing flexibility and supports more complex navigation scenarios.

BREAKING CHANGE: The `RedirectFn` can now return `Observable` or
`Promise`. Any code that directly calls functions returning this type
may need to be adjusted to account for this.

PR Close #60863
2025-04-23 13:38:49 +02:00
Andrew Scott
953c4b2580 feat(core): Move zoneless change detection to dev preview (#60748)
This commit moves zoneless from experimental to developer preview.

* Update tag on provider API
* Remove "experimental" from provider name
* Move documentation from "experimental features" to "Best practives ->
  Performance" (at least temporarily until there is a better place)

BREAKING CHANGE: `provideExperimentalZonelessChangeDetection` is
renamed to `provideZonelessChangeDetection` as it is now "Developer
Preview" rather than "Experimental".

PR Close #60748
2025-04-23 11:47:56 +02:00
Philipp Burgmer
2419060fef fix(router): relax required types on router commands to readonly array (#60345)
Only require a readonly array as input for router commands instead of a writable array. Router itself does not need writable access to the array of commands. If router requires a writable array somebody on the outside would have to spread a readonly array to a new writable array. We can avoid this by just require what route actually needs.

Fixes #60269

BREAKING CHANGE: Several methods in the public API of the Router which
required writable arrays have now been updated to accept readonly
arrays when no mutations are done.

PR Close #60345
2025-04-17 16:21:57 +02:00
Andrew Scott
0bb4bd661e feat(router): Add ability to directly abort a navigation (#60380)
This commit adds the ability to directly abort a navigation through the
`Router.getCurrentNavigation()?.abort()` method. While there are no
feature requests for this, it is a feature that will be necessary for
integration with the navigation API. The API enables better tracking of
an ongoing navigation for SPAs and a site visitor can cancel a
navigation by clicking the stop button in the browser. While this could
technically be done on the transition with an internal jsdoc comment to
hide it from application developers, there's no need.

With this feature, I believe it would be possible to create somewhat of a shim
to integrate with the navigation API even before the router has full support
using the router events to control a deferred navigation that never
commits the URL and always aborts itself on navigation end.

PR Close #60380
2025-04-02 17:30:27 +00:00
Andrew Kushnir
6d3f5752f2 refactor(router): switching to relative imports within the router package (#60557)
This commit updates scripts within `packages/router` to relative imports as a prep work to the upcoming infra updates.

PR Close #60557
2025-04-01 14:54:05 +00:00
Lukas Spirig
ff98ccb193 feat(router): support custom elements for RouterLink (#60290)
PR Close #60290
2025-03-28 12:16:09 +00:00
Andrew Scott
0142ae1c8e refactor(router): Update tests to not use deprecated string tokens (#60378)
This replaces string tokens in the router tests with functional guads.

PR Close #60378
2025-03-28 11:50:11 +00:00
Kristiyan Kostadinov
5e209cb560 feat(core): remove TestBed.get (#60414)
`TestBed.get` isn't type safe and has been deprecated for several years now. These changes remove it from the public API and a follow-up change will add an automated migration to `TestBed.inject`.

BREAKING CHANGE:
* `TestBed.get` has been removed. Use `TestBed.inject` instead.

PR Close #60414
2025-03-19 15:52:26 +01:00
Andrew Scott
0b6084e1bf refactor(router): split remainder of describes in integration test file (#60313)
to more easily navigate and identify different suites of integration tests,
this commit splits them into several different files

PR Close #60313
2025-03-11 17:13:27 -07:00
Andrew Scott
647550918f refactor(router): split integration test file (#60311)
to more easily navigate and identify different suites of integration tests,
this commit splits them into several different files

PR Close #60311
2025-03-10 16:03:54 -07:00
Andrew Scott
7c12cb1df9 feat(router): Allow resolvers to read resolved data from ancestors (#59860)
This commit updates the resolver execution to ensure that resolvers in
children routes are able to read the resolved data from anything above
them in the route tree. Because resolvers on one level block execution
of those below, it seems more of an oversight in the initial
implementation than anything else that this wasn't already possible.

resolves #47287

PR Close #59860
2025-02-25 12:34:40 -05:00