Instead of fiddling manually with the imports, which worked well, but
comes at a cost of complexity— we are now using the canonical import
manager. This simplifies deletion, insertion and updating of imports.
Notably, our import manager is not super great at preserving whitespaces
right now, but we assume a formatter runs over migrated code anyway.
PR Close#57318
Introduces a best effort mode for the signal input migration. This mode
can be used to aggresively migrate as much as possible, ignoring most
of the incompatibility reasons, like "writes to the input".
PR Close#57318
Errors during change detection from `ApplicationRef.tick` are only
reported to the `ErrorHandler`. By default, this only logs the error to
console. As a result, these errors can be missed/ignored and allow tests
to pass when they should not. This change ensures that the errors are
surfaced. Note that this is already the behavior when zoneless is
enabled.
BREAKING CHANGE: Errors that are thrown during `ApplicationRef.tick`
will now be rethrown when using `TestBed`. These errors should be
resolved by ensuring the test environment is set up correctly to
complete change detection successfully. There are two alternatives to
catch the errors:
* Instead of waiting for automatic change detection to happen, trigger
it synchronously and expect the error. For example, a jasmine test
could write `expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()`
* `TestBed` will reject any outstanding `ComponentFixture.whenStable` promises. A jasmine test,
for example, could write `expectAsync(fixture.whenStable()).toBeRejected()`.
As a last resort, you can configure errors to _not_ be rethrown by
setting `rethrowApplicationErrors` to `false` in `TestBed.configureTestingModule`.
PR Close#57200
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 updates serialization and hydration i18n logic to take into account situations when i18n blocks are located within "skip hydration" blocks.
Resolves#57105.
PR Close#57299
Previously, if a component injects a `ViewContainerRef`, the post-hydration cleanup process doesn't visit inner views to cleanup dehydrated views in nested LContainers. This commit updates the logic to recognize this situation and enter host LView to complete cleanup.
Resolves#56989.
PR Close#57300
By default, we don't migrate inputs if they are part of e.g. `@if` for
now. That is because we don't have the template narrowing feature
available yet.
To improve impact of the migration until we have the narrowing, we add
some additional checks that allow us to migrate instances of inputs that
are part of e.g. `@if` but are actually not used inside (and hence are
guaranteed to be _not_ narrowed).
PR Close#57308
This commit updates the inside/outside NgZone detection of the hybrid CD
scheduling to track the actual instance of the NgZone being used rather
than the name "Angular" (how `isInsideAngularZone` works). This allows
the scheduling to work correctly when there are multiple versions of
Angular running on the page.
fixes#57261
PR Close#57267
Currently in some scenarios the compiler generates code like `null as any ? foo : bar` which will be invalid with [an upcoming TypeScript change](https://devblogs.microsoft.com/typescript/announcing-typescript-5-6-beta/#disallowed-nullish-and-truthy-checks). These changes switch to generating `0 as any` which is exempt from the change.
**Note:** I'm not starting the work to fully get us on TS 5.6 until the 18.2 release comes out, but this change is necessary to unblock an internal team.
PR Close#57303
This changes the migration so that we don't generate `_1` suffixes when
a temporary variable wouldn't conflict with any variables in the lexical
scope.
In addition, if we discover conflicts, we try alternative suffixes that
seem more natural and follow style guides. E.g. `Value`, `Val` or
`Input`.
PR Close#57292
Currently we use some short variable names like `t` and `r` in the generated factory functions. They can conflict with local symbols with the same names, if they're used for DI.
These changes rename the parameters to reduce the change for conflicts.
Fixes#57168.
PR Close#57181
This commit addresses a performance bottleneck in the `interpolatedSignalNotInvoked` extended
diagnostic by querying directive metadata instead of consulting the type-checker to determine if
a property binding corresponds with an input.
Fixes#57287
PR Close#57291
These changes replace most usages of `removeChild` with `remove`. The latter has the advantage of not having to look up the `parentNode` and ensure that the child being removed actually belongs to the specific parent.
The refactor should be fairly safe since all the browsers we cover support `remove`. [Something similar was done in Components](https://github.com/angular/components/pull/23592) some time ago and there haven't been any bug reports as a result.
PR Close#57203
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
BREAKING CHANGE: `fakeAsync` will now flush pending timers at the end of
the given function by default. To opt-out of this, you can use `{flush:
false}` in options parameter of `fakeAsync`
PR Close#57240
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
PR Close#57239
Similar to a previous fix that intended to make the JIT transforms
compatible with pre-transforms like e.g. Tsickle, we need to solve
an additional issue where the class properties are synthetic and result
in an `getSourceFile() => undefined` invocation that breaks the import
insertion, causing errors like:
```
TypeError: Cannot read properties of undefined (reading 'fileName')
```
PR Close#57262
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
PR Close#57137
Angular's template files are not valid TypeScript. Attempting to get suggestion
diagnostics from the underlying TypeScript language service will result in
a large amount of false positives. Only actual TypeScript files should
be analyzed by the underlying TypeScript language service for suggestions.
PR Close#56241
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 was an old feature that mapped shift + click (et al) to "clickmod". This doesn't really make sense to add to Angular, so let's remove it.
PR Close#57201