This allows passing errors and disabled reasons that did not originate
from `@angular/forms/signals` in case the the control is being used
separately from the forms system
PR Close#63455
Removes custom handling of emptiness in several of the validators and
replaces it with a common `isEmpty` check. The common empty check
considered the following values to be empty: `null`, `undefined`, `''`,
`false`, `NaN`
Generally most validators should treat an empty value as valid. This
aligns with both the behavior or native HTML validators and reactive
forms validators.
As an example, consider an optional email field. If the email validator
considered empty string to be an invalid email, there would be no way
for the user to not enter it.
There are several exceptions to this rule:
- `required` whose entire purpose is to ensure that the field is *not*
empty
- `validateStandardSchema` which should subject all values including
empty ones to the specified standard schema. It is up to the schema to
decide whether an empty value is valid or not
- `validate`/`validateAsync` which leaves it up to the user's custom
validation logic to decide if an empty value is valid.
PR Close#63456
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
To aid in hitting external breaking change deadlines without pressure
of fixing everything in g3 first, add an internal opt out flag.
This also adds a privately exported provider to revert to the old
rxjs-based behavior, which can be synchronous, until any issues that
come up are addressed.
PR Close#62994
This is effectively a revert of https://github.com/angular/angular/commit/72e6a948bb8ec58f14b87d297d5f81baf2e1942d.
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
The new animations was not correctly looking for the `.` when parsing bindings. This resulted in arbitrary event bindings creating animate.leave instruction calls.
fixes: #63466
PR Close#63470
This commit introduces an experimental version of a new signal-based forms API for Angular. This new API aims to explore how signals can be leveraged to create a more declarative, intuitive, and reactive way of handling forms.
The primary goals of this new signal-based approach are:
* **Signal-centric Design:** Place signals at the core of the forms experience, enabling a truly reactive programming model for form state and logic.
* **Declarative Logic:** Allow developers to define form behavior, such as validation and conditional fields, declaratively using TypeScript. This moves logic out of the template and into a typed, testable schema.
* **Developer-Owned Data Model:** The library does not maintain a copy of data in a form model, but instead read and write it via a developer-provided `WritableSignal`, eliminating the need for applications to synchronize their data with the form system.
* **Interoperability:** A key design goal is seamless interoperability with existing reactive forms, allowing for incremental adoption.
* **Bridging Template and Reactive Forms:** This exploration hopes to close the gap between template and reactive forms, offering a unified and more powerful approach that combines the best aspects of both.
This initial version of the experimental API includes the core building blocks, such as the `form()` function, `Field` and `FieldState` objects, and a `[control]` directive for binding to UI elements. It also introduces a schema-based system for defining validation, conditional logic, and other form behaviors.
Note: This is an early, experimental API. It is not yet complete and is subject to change based on feedback and further exploration.
Co-authored-by: Kirill Cherkashin <kirts@google.com>
Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
Co-authored-by: Leon Senft <leonsenft@users.noreply.github.com>
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>
Co-authored-by: Michael Small <michael-small@users.noreply.github.com>
PR Close#63408
This commit updates provider definitions that relied on the `deps` array
with `new Optional()` and `new SkipSelf()` to instead use the modern
`inject(..., { optional: true, skipSelf: true })` API.
Previously:
deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
Now:
const parent = inject(KeyValueDiffers, { optional: true, skipSelf: true });
**Bundle size reduction**: `Optional` and `SkipSelf` are runtime values
created by `makeParamDecorator()`. Even in production builds, esbuild
and other bundlers must keep their factory code because they are
referenced with `new Optional()` / `new SkipSelf()`. With `inject()`,
those classes are no longer referenced, allowing them and the
`makeParamDecorator` scaffolding to be tree-shaken when unused.
As a result, production bundles can drop both `Optional`, `SkipSelf`, and
their supporting factory code when not used elsewhere, reducing code size
while keeping the same behavior.
PR Close#63386
Add support for the Fetch API's responseType property in HttpResponse and HttpErrorResponse when using HttpClient with the withFetch provider.
PR Close#63043
When toggling visibility on an element over and over, the enter animations were supposed to be cancelled and then the classes removed. There was a race condition happening that resulted in the cancelled animation being the leave animation. Rather than using the animation.cancel functionality, it's safer to just remove the enter classes.
fixes: #63439
PR Close#63442
Annotate the `new Version(...)` call with `/* @__PURE__ */` to signal to
optimizers that the constructor is side-effect free.
Without this hint, bundlers such as Terser or ESBuild may conservatively
retain the `VERSION` instantiation even when unused. With the annotation,
the constant can be tree-shaken away in production builds if not referenced,
reducing bundle size.
PR Close#63400
This commit prevents lazy injection of the internal `ErrorHandler` from a destroyed injector, which would otherwise result in a secondary "destroyed injector" error.
The `handleUncaughtError` function is used in a wrapped event listener that invokes the `ErrorHandler` if the listener throws. A simple case in a micro-frontend application:
```ts
onNavigationToAnotherApp() {
this.appRef.destroy();
do_some_stuff_ie_loggin_that_may_throw();
}
```
If the function throws an error, Angular attempts to inject the `ErrorHandler` from a destroyed injector.
PR Close#62275
When declaring directives, the standalone flag is set to true by default in current Angular versions.
The docs for the directive decorator should correctly explain the default behavior, while still mentioning when to set it to false.
PR Close#63329
The 4 second removal timeout was applying in all cases, but it should only actually apply to the situation where the event binding syntax is used for animate.leave. This ensures that's the only case in which it'll apply.
PR Close#63393
Deprecated since v5. Use `upgrade/static` instead, which also supports aot.
BREAKING CHANGE: `UpgradeAdapter` is no longer available. Use
`upgrade/static` instead
PR Close#61659
The animate instructions were getting applied to the container comment nodes as well as the element nodes. This prevents that on the compiler level.
fixes: #63371
PR Close#63390
This commit drops the `X-Request-URL` header. It was a non-standard HTTP response header, deprecated long ago and never part of any official specification. Modern browsers now expose the final URL via the `XMLHttpRequest.responseURL` property, as defined in the WHATWG spec.
PR Close#61943
This fixes the rare case that someone uses binding syntax with `animate.leave` providing a value with a string that has spaces in it. For example:
```
<example `[animate.leave]="'class-a class-b"` />
```
fixes: #63365
PR Close#63366
Change direct deps in bazel targets and import specifiers within files to maintain strict deps requirements ahead of enabling strict deps tests in the repo
PR Close#63323
There's special logic in place to prevent duplicate nodes from showing up in the case when an `@if` toggles a view quickly. This had the unfortunate side effect of causing `@for` leave animations to get cancelled when an add and remove happened simultaneously, even if it was a different index. This fix prevents that from happening in the `@for` loop case.
fixes: #63307
PR Close#63328
The `FormArrayDirective` will allow to have a `FormArray` as a top-level form object.
* `NgControlStatusGroup` directive will be applied to the `FormArrayDirective`
* `NgForm` will still create a `FormGroup`
Fixes angular#30264
BREAKING CHANGE: This new directive will conflict with existing FormArray directives or formArray inputs on the same element.
PR Close#55880
Ts 5.9 introduced a regression coming from 5.8 when parenthesis aren't generated for expressions like (`(a ?? b) && c`).
This fix works around this explicitly specifying that we want to keep those parenthesis that we're aware of in this specific case;
This change can be reverted if the root issue (https://github.com/microsoft/TypeScript/issues/61369) is fixed. (but let's keep the tests in any case for the coverage)
fixes#63287
PR Close#63292
Fixes that the HMR extraction logic didn't accoubnt for expressions with type arguments (e.g. `viewChild('foo', {read: TemplateRef<unknown>})`).
Fixes#63240.
PR Close#63261
In the context of TypeScript (TS), a re-exported symbol is considered a distinct symbol.
This means that a developer can choose to import either the re-exported symbol or
the original symbol. However, in the context of Angular, the re-exported symbol
is treated as the same component because it uses the same selector.
This pull request will utilize the most recent re-export component file to
resolve the module specifier.
PR Close#62585