This commit introduces an interface for `toSignal` options to mirror that of
`toObservable`, and adjusts docs for both symbols. It also adds the ability
for `toSignal` to manually specify `DestroyRef` (similarly to
`toObservable` accepting an injector) or for `toSignal` automatic cleanup to
be disabled (in which case the subscription persists until the Observable
completes). Either option allows `toSignal` to be used outside of a DI
context, like `toObservable`.
PR Close#50071
It might happen that the lifecycle scope represented by DestroyRef becomes
invalid before an onDestroy hook is registered (ex. injector or component
instance got destroyed). In such cases registration of the onDestroy hooks
should no longer be possible.
Fixes#49658
PR Close#49804
The new asReadonly method on the WritableSignal interface makes
it possible to create readonly instance of a writable signal.
Readonly signals can be accessed to read their value,
but can't be changed using set, update or mutate methods.
PR Close#49802
The initial value used for signals by default is now `undefined`. In
addition, there is a new option to express that the signal should emit a
value synchronously (`requireSync: true`). When this value is specified,
the function will throw _on creation_ if the subscribing to the
`Observable` does not result in a synchronous emit.
PR Close#49769
This change makes is possible to use async functions
(ones returning a promise) as effect run functions.
To make it possible, the signature of the effect function
changed: effect cleanup function is registered now
(using a dedicated callback passed to the effect creation)
instead of being returned from the effect function.
PR Close#49783
This commit updates the logic to detect a situation when hydration support was enabled only on the client. If that happens, Angular produces a warning in a console with a link to the error guide.
PR Close#49743
Currently, non-destructive hydration for i18n blocks is not supported (but support is coming!).
This commit updates the serialization logic from throwing an error when it comes across an i18n
block to annotating a component with a skip hydration flag.
PR Close#49722
Previously, attempting to turn off the `experimentalDecorators` TypeScript configuration
option within an Angular project would result in build time errors. These errors were due
to an exposed Decorator signature from `@angular/core` that TypeScript thought was incompatible
with standard decorators. However, Angular's class decorators (`Component`, `Directive`, `Pipe`,
`Injectable`, `NgModule`) are actually already compatible with standard decorators. The export types for
the decorators only needed to be updated to reflect that compatibility. With the updated exported types,
applications will now successfully compile and execute in AOT mode with one important dependency injection
caveat explained in the note below.
For JIT mode applications that are built with the Angular CLI, `@ngtools/webpack`, or use `tsickle`,
there were also no additional changes required. These tools automatically convert property decorators
(now called field decorators) at build time to store Angular property metadata directly on the relevant
class. Building with these tools is the overwhelmingly common method of building an application. Any
applications that do not use one of these tools will not function at runtime in JIT mode if using standard
decorators. The behavior and code for when experimental decorators is enabled has been left intact.
NOTE: Angular constructor dependency injection that requires parameter decorators is not supported.
The standard decorator specification does not support parameter decorators. The `inject` function must be
used for all cases that previously required a parameter decorator. This includes such decorators as `Inject`,
`Optional`, `Self`, `SkipSelf`, `Host`, and `Attribute`. Constructor dependency injection that relies only
on the supplied parameter type will continue to function as expected if using AOT; as well as in JIT mode
if using the Angular CLI, `@ngtools/webpack` directly, or `tsickle`.
Documentation for the `inject` function can be found at: https://angular.io/api/core/inject
The decorator specification proposal can be found at: https://github.com/tc39/proposal-decorators
PR Close#49492
The `ReflectiveInjector` symbol has been deprecated in v5 (11 major versions ago). This commit removes ReflectiveInjector and related symbols.
BREAKING CHANGE: The `ReflectiveInjector` and related symbols were removed. Please update the code to avoid references to the `ReflectiveInjector` symbol. Use `Injector.create` as a replacement to create an injector instead.
PR Close#48103
To match the behaviour of Array.filter, typeguards can now be used on QueryList.filter to narrow the return type.
Fixes#38446
BREAKING CHANGE: QueryList.filter now supports type guard functions, which will result in type narrowing. Previously if you used type guard functions, it resulted in no changes to the return type. Now the type would be narrowed, which might require updates to the application code that relied on the old behavior.
PR Close#48042
This change exposes the onDestroy callback on the ApplicationRef
as the public API. It is useful for cases where people need to
execute cleanup logic on application teardown.
Closes#49087
PR Close#49677
This commit adds a provider function that allows developers to configure
the `NgZone` instance for the application. In the future, this provider
will be used for applications to specifically opt-in to change detection
powered by ZoneJS rather than it being provided by default.
This API does _not_ specifically provide support for developers to define their own
`NgZone` implementation or opt in to `NoopNgZone` directly. Both of
these are possible today, but are effectively unsupported (applications
that use these are left to their own devices to run change detection at
the appropriate times). That said, developers can still use DI in
`bootstrapApplication` to provide an `NgZone` implementation instead,
it's just not specifically available in the
`provideZoneChangeDetection` function.
PR Close#49557
* Prevent reads of signals during the notification process. This shouldn't
ever be triggered by user code but is more of a preventative for
internal misuse. Reading a signal during notification would/could create
glitches where the values being read are not updated to reflect the
values being updated by the notification.
* Prevent signal writes inside of computed's. These are meant to be
derived values and should not have any side-effects like writing new
values to other signals
* Prevent signal writes inside of effects by default. Writing to signal
values during the execution of an effect can lead to the
`ExpressionChangedAfterItHasBeenCheckedError` if writing to signals
that represent global state which is read in a parent component. This is
mostly just a problem for `OnPush`/`CheckAlways` components, but with
signals being new and pure signal components not even available yet,
it will be the majority for a long time.
PR Close#49631
This commit implements an RxJS operator `takeUntilDestroyed` which
terminates an Observable when the current context (component, directive,
etc) is destroyed. `takeUntilDestroyed` will inject the current `DestroyRef`
if none is provided, or use one provided as an argument.
PR Close#49154
This commit adds the basic sketch for the implementation of `fromObservable`
and `fromSignal`, the two basic primitives which form the RxJS interop layer
with signals.
PR Close#49154
This commit adds the infrastructure for `@angular/core/rxjs-interop`, a new
core entrypoint which provides bidirectional interoperability between
Angular's built-in reactivity system of synchronous signals, and the RxJS
`Observable` abstraction.
The new entrypoint is set up as an empty shell in this commit, with its
implementation to follow in a followup.
PR Close#49154
We've been experimenting with the DeepReadonly type that would make
signal values deeply read-only and prevent accidental changes without
going to the owner of data. What we've found out during the experiments
is that additional safety net has more drawbacks than benefits: it just
introduces too much friction to be practical for daily usage.
PR Close#49154
This change extends the effect API surface so effects can, optionally,
return a cleanup function. Such function, if returned, is executed
prior to the subsequent effect run.
PR Close#49625
This commits adds `makeStateKey`, `StateKey` and `TransferState` methods in `@angular/core` as public API and deprecated the same exported symbols in `@angular/platform-browser`.
DEPRECATED: `makeStateKey`, `StateKey` and `TransferState` exports have been moved from `@angular/platform-browser` to `@angular/core`. Please update the imports.
```diff
- import {makeStateKey, StateKey, TransferState} from '@angular/platform-browser';
+ import {makeStateKey, StateKey, TransferState} from '@angular/core';
```
PR Close#49563
Signal functions are marked with a `[SIGNAL]` symbol property, which was
previously set to `true`.
This commit changes the `[SIGNAL]` property to have the `ReactiveNode` as
its value instead. This doesn't change the behavior of the signal library
itself, but exposes the signal internals in a way where developer tooling
can look at any signal and interact with its dependency graph.
PR Close#49529
This commit adds a `DeepReadonly` type to the signals API, and makes signal
getters return an immutable version of their value type. This doesn't
prevent all mutation but adds some friction against modifying the values
within signals outside of the proper mutation APIs.
PR Close#49529
The `effect` implemented in the signal library is useful for testing but
does not integrate with Angular. This commit moves that code to the
actual framework package and integrates it with automatic cleanup via
`DestroyRef`. A simpler effect implementation is used in the signal tests to
test the `Watch` primitive.
Further commits will update the scheduling to tie effects together with
change detection.
PR Close#49529
This commit switches the `signal` and `computed` APIs to accept an optional
options argument as their second argument, instead of an equality function
directly. The equality function has moved to an option in the options
argument.
PR Close#49529
This commit renames the `SettableSignal` interface to align with recent
naming changes. `WritableSignal` is considered a more suitable name since
it supports more mutation operations than just directly setting.
PR Close#49529
This commit adds an assertion function to the public API, which allows
authors of functions which rely on `inject` to validate that they're being
called with the right context. This mostly produces a nicer error message
than calling `inject()` and relying on Angular's default error message for
that.
PR Close#49529
The `moduleId` directive field does not have any effect as of Ivy. In
View Engine it was used for resolving template and styles relative
to the component source location- but ultimately this is not needed
as the Angular compiler knows the source file location at build time,
and at runtime never even consulted `moduleId`. An XHR is always issue
using the extact specified URL.
For Angular CLI users, relative URLs in JIT are still possible because
the CLI has a TS transform that will replace the references with actual
Webpack imports.
`moduleId` does not seem worth keeping in the future, as it's not used
currently, and even if we would consider supporting relative JIT resource
URLs through it, it would be deeply coupled to CommonJS `module.id`.
DEPRECATED: The `@Directive`/`@Component` `moduleId` property is now
deprecated. It did not have any effect for multiple major versions and
will be removed in v17.
PR Close#49496
`entryComponents` have been deprecated since version 9, because with Ivy they weren't necessary. These changes remove any remaining references.
BREAKING CHANGE:
* `entryComponents` has been deleted from the `@NgModule` and `@Component` public APIs. Any usages can be removed since they weren't doing anyting.
* `ANALYZE_FOR_ENTRY_COMPONENTS` injection token has been deleted. Any references can be removed.
PR Close#49484
This adds user friendly error messages outlining exactly where hydration
mismatches occur and what was expected with easy to read stringified
DOM. It also includes a pointer to exactly where the mismatch happened
and lets the user know what was expected.
PR Close#49502
This change makes it possible to remove a previously registered destroy
callback - to do so it is enough to call the unregistration function
returned from the onDestroy method call.
PR Close#49493
Before this change the effect creation function was returning
an instance of the Effect interface with explicit destroy and
schedule operations. This commit makes the following changes
to the return type of effect:
- the interface is renamed from Effect to EffectRef;
- the only available method on this interface is destroy.
We want to tighten the interface in question so only a minimal
set of useful operations is initially exposed.
PR Close#49490
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.
Fixes#37706.
PR Close#49468
This reverts commit 13dd614cd1.
This breaks a g3 Typescript compilation tests where diagnostics are
expected for a missing input in the component.
PR Close#49467
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs.
These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`.
This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material.
Fixes#6361.
PR Close#49444
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.
Fixes#37706.
PR Close#49453
This reverts commit 1a6ca68154.
This breaks tests in google3 which might be depending on private APIs. We
need to update these tests before we can land this PR.
PR Close#49449
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.
Fixes#37706.
PR Close#49304