`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
PR #51670 removed the usage of `const enum`. As a consequence HttpStatusCode that were previously inlined now pull and retains the (fairly large) `HttpStatusCode` enum.
By intermediate constants, we prevent the framework from pulling this big enum by default.
PR Close#55434
Expose `HTTP_TRANSFER_CACHE_ORIGIN_MAP` injection token in public api. This is useful when different origins are used to access the same APIs between server and browser.
Fixes#53702
PR Close#55274
This commit introduces a check plus an associated warning for situations where
the combination of the collection change and the tracking expression resulted
in the entire view structure managed by @for to be re-created.
The check uses the following conditions before raising a warning:
- the entire collection was re-created and there were no other operations (ex.: move);
- views in a collection are considered "expensive" to re-create;
- a developer is using tracking by identity.
The last condition tries to capture cases where changes to immutable data
collections can cause significent performance and / or corectness problems.
Note that this warning might be "overreacting" and report cases where
the collection re-creation is the intended behavior. Still, the assumption is that
most of the time it is undesired.
PR Close#55314
This commit fixes an error in a previous commit which attempted to read
`data` from the first item in the apply args array, even if it was not
defined.
PR Close#55465
This commit removes of migrations introduced in version 17, along with the relocation of a migration from 17.3 to version 18. This ensures that this is ran for users who may have updated from one minor to another without executing `ng update`
PR Close#55391
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit adds helpful stack information for the case when change
detection continues to be triggered in the event loop and would cause
the browser to freeze.
PR Close#55231
There is an existing pattern that zone-based applications use to avoid
`ExpressionChangedAfterItHasBeenCheckedError` which is also used in
`NgModel`: update the state in a microtask instead of doing it
synchronously. This defers the state update to another round of change
detection, and with ZoneJS, also still executes in the same event loop.
These types of changes across multiple rounds of change detection were
still executed before the browser paint.
This update allows the `NgModel` workaround to continue working in
Zoneless. This may not be permanent and is certainly still not
advisable. Render hooks (`afterNextRender`/`afterRender`) will execute between these
rounds of change detection when they are intended to be run after all
DOM updates completed.
PR Close#55231
This commit ensures we correctly handle the exit from the zone.run in
the zoneless scheduler. Run coalescing would delay the `onMicrotaskEmpty` event
until after we have exited the change detection triggered by the
zoneless scheduler and mean that the subscription cannot determine if
`ApplicationRef.tick` should be skipped.
PR Close#55352
For ideal DOM usage, you would not unwrap an ElementRef outside of the browser. However, it's reasonable to want to find the tag name of the host node on the server, and so this introduces a HOST_TAG_NAME token that can be injected to read this value.
PR Close#54751
Flip `stopPropagation` constructor parameter default to `false` for
`EventContract` and `EventContractMultiContainer`. Change type for
`EventContract` to `false` to indicate that no values besides `false`
should be passed. This enables removing all usages of `stopPropagation`
in `EventContract` and leaving only usages of `stopPropagation = true`
for `EventContractMultiContainer`.
PR Close#55351
When `cleanUp` is called `containerManager` is set to null. Currently
the `EventContract` API assumes that users know not to call further
methods on `EventContract`, but this lead to a bug in a downstream app,
b/333750059. So instead, this makes a defensive check to make sure it's
not null.
PR Close#55353
This commit integrates the JSA contract binary into the NPM package and ensures its accessibility by including it in the package exports. This adjustment is essential for enabling Angular CLI to effectively access and inject the script. Additionally, sourcemaps are removed from the minified bundle to prevent their inclusion in the HTML page.
PR Close#55361
This commit loosens the restrictions on calling `ComponentFixture.detectChanges`
when using the zoneless scheduler. While we don't necessarily think it's
a good idea, the thought is that it's unnecessary mental overhead to
diverge behaviors in the API when zoneless is enabled versus when it is
not. Instead, these opinionated restrictions can be considered when we
look at new testing APIs.
PR Close#55325
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
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.
We will try to update the coalescing behavior of ZoneJS in a future PR
to also just use the patched version of the timers instead of the
"fakeTopEvent" workaround with the native timers.
PR Close#55367
This commit ensures that manually calling ApplicationRef.tick will
result in any scheduled change detections being canceled. There is no
need for the scheduled one to run because it was manually done by the
`tick` already.
PR Close#55290
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.
In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.
Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.
BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.
PR Close#55342
Right now this binary sits at 9.5kb. Additional changes to the library will
be done to reduce the binary size, such as converting event_type from
an enum to an object, and other code size reductions.
PR Close#55319
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit removes the long-deprecated Testability methods that track
pending tasks. This is done by NgZone today and will be done by other
APIs in zoneless.
BREAKING CHANGE: Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.
PR Close#53768
This commit adds a configuration option to zone-based change detection
which allows applications to enable/disable the zoneless scheduler.
When the zoneless scheduler is enabled in zone-based applications,
updates that happen outside the Angular zone will still result in a
change detection being scheduled. Previously, Angular change detection
was solely based on the state of the Angular Zone.
PR Close#55252
Expect that the number of template executions is `===` to a number, rather than expect that it
does not contain a number. As they were, these expectations would pass regardless of the expected
value.
PR Close#55294
1: Remove USE_EVENT_PATH, which has no users.
2: Create a new `EventActionInfo` object to represent actions, update all `EventInfoWrapper` users.
3: Fix `stopPropagation` behavior in JSAction Dispatcher - it should only `stopPropagation` if an action is found, which is only known during normal dispatch rather than global.
PR Close#55182
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.
PR Close#55226
Now that #55092 has merged, we now consistently get the `setTimeout` and
`rAF` implementations that are not patched by zone. There's no longer a
need to run them in the root zone.
PR Close#55230
PR #55099 updated zoneless behavior to treat all views attached to
`ApplicationRef` as `OnPush`. Put another way, Zoneless change detection
will only refresh view trees that notified Angular of a change. This
generally works as expected but there was one situation where it did
not.
Some views are logically linked to their declaration locations and
should refresh when the declaration refreshes. These views are called
"transplanted views" and work correctly when inserted into another view
container. This change updates the logic to also work when they are
attached directly to `ApplicationRef`.
PR Close#55154
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.
PR Close#55215