Commit graph

52 commits

Author SHA1 Message Date
Paul Gschwendtner
c687b8f453 feat(core): expose new output() API (#54650)
This commit exposes the new `output()` API with numerous benefits:

- Symmetrical API to `input()`, `model()` etc.
- Fixed types for `EventEmitter.emit`— current `emit` method of
  `EventEmitter` is broken and accepts `undefined` via `emit(value?: T)`
- Removal of RxJS specific concepts from outputs. error channels,
  completion channels etc. We now have a simple consistent
  interface.
- Automatic clean-up of subscribers upon directive/component destory-
  when subscribed programmatically.

```ts
@Directive({..})
export class MyDir {
  nameChange = output<string>();     // OutputEmitterRef<string>
  onClick = output();                // OutputEmitterRef<void>
}
```

Note: RxJS custom observable cases will be handled in future commits via
explicit helpers from the interop.

PR Close #54650
2024-03-06 12:34:38 +01:00
Kristiyan Kostadinov
243b94c6e1 refactor(compiler-cli): fix regression in two-way bindings to inputs with different getter/setter types (#54252)
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.

PR Close #54252
2024-02-07 16:36:13 +00:00
Kristiyan Kostadinov
702ab28b4c feat(core): add support for model inputs (#54252)
Adds support for model inputs in the framework. `model()` returns a writable signal that implicitly defines a input/output pair that can be used either in two-way bindings to keep two values in sync or by binding individually to the input and output. When the value of the `model` changes, it will emit an event with the current value.

Furthermore, these changes expand two-way bindings to accept `WritableSignal`. This will make it easier to transition existing code to signals in a backwards-compatible way.

Example:

```ts
@Directive({
  selector: 'counter',
  standalone: true,
  host: {
    '(click)': 'increment()',
  }
})
export class Counter {
  value = model(0);

  increment(): void {
    this.value.update(current => current + 1);
  }
}

@Component({
  template: `<counter [(value)]="count"/> The current count is: {{count()}}`,
})
class App {
  count = signal(0);
}
```

PR Close #54252
2024-02-07 16:36:09 +00:00
Pawel Kozlowski
3a2ce9e0a2 refactor(core): add error code for required query results (#54103)
This commit introduces a dedicated error code for queries that require
results but none are available.

PR Close #54103
2024-02-06 15:04:36 +00:00
Paul Gschwendtner
1df95cd1c1 refactor(core): improve error message and add guide for required inputs (#53808)
Whenever a required input is accessed too early in a
directive/component, the signal input will throw an error.

This is necessary so that we can support required inputs
with intuitive typings that do not include `undefined` for
the short period of time where Angular is creating the component and
then assigning inputs later (Angular currently has no way of setting
inputs as part of the class creation when `new Dir()` happens)

PR Close #53808
2024-01-10 12:21:05 +00:00
Andrew Scott
dfcf0d5882 fix(core): afterRender hooks now only run on ApplicationRef.tick (#52455)
The `afterRender` hooks currently run after `ApplicationRef.tick` but
also run after any call to `ChangeDetectorRef.detectChanges`. This is
problematic because code which uses `afterRender` cannot expect the
component it's registered from to be rendered when the callback
executes. If there is a call to `ChangeDetectorRef.detectChanges` before
the global change detection, that will cause the hooks to run earlier
than expected.

This behavior is somewhat of a blocker for the zoneless project. There
is plenty of application code that do things like `setTimeout(() =>
doSomethingThatExpectsComponentToBeRendered())`, `NgZone.onStable(() =>
...)` or `ApplicationRef.onStable...`. `ApplicationRef.onStable` is a
should likely work similarly, but all of these are really wanting an API
that is `afterRender` with the requirement that the hook runs after the
global render, not an individual CDRef instance.

This change updates the `afterRender` hooks to only run when
`ApplicationRef.tick` happens.

fixes #52429
fixes #53232

PR Close #52455
2024-01-08 11:30:27 -08:00
Andrea Canciani
fc9ba3978c refactor: fix a number of typos throughout the codebase (#52249)
Fix some typos such as `boostrap`, `propery` and more, both in
documentation and in code (comments, identifiers).

PR Close #52249
2023-10-25 16:51:24 -07:00
Andrew Scott
76152a5fc6 fix(core): Ensure backwards-referenced transplanted views are refreshed (#51854)
This commit runs change detection in a loop while there are still dirty
views to be refreshed in the tree. At the moment, this only applies to
transplanted views but will also apply to views with changed signals.

fixes angular#49801

PR Close #51854
2023-10-24 14:50:18 -07:00
Andrew Kushnir
e2fc506a89 refactor(core): report @defer errors using ErrorHandler (#52320)
This commit updates the code to report errors via `ErrorHandler` instance.
For dependency loading problems, errors are reported only when `@error` block is not provided.

PR Close #52320
2023-10-24 09:24:43 -07:00
Paul Gschwendtner
496ee47b3d docs: add error guide for assertNotInReactiveContext. (#52138)
Adds an error guide for `assertNotInReactiveContext` and provides some
more context/ and guidance for fixing common errors.

PR Close #52138
2023-10-10 13:56:56 -07:00
Alex Castle
048f400efc feat(core): add warnings for oversized images and lazy-lcp (#51846)
Add warnings for two image-related performance problems that apply beyond just apps using NgOptimizedImage.

PR Close #51846
2023-10-06 12:14:32 -07:00
Paul Gschwendtner
4427e1ebc2 feat(core): create function to assert not running inside reactive context (#52049)
Some functions or code should never run inside reactive contexts. A
function to assert that will help putting guard rails in place.

PR Close #52049
2023-10-05 11:08:05 -07:00
Payam Valadkhan
c6b9a3ea6c refactor(core): forbid rendering orphan components in local compilation mode (#51726)
Certain code patterns and tools in Google (and possibly 3P world) lead to the situation that a component is bootstrapped/rendered without its ng-module being loaded in the browser. Technically speaking this should be an anti-pattern since the ng-module could contain some runtime logic (e.g., providing something, calling some services, etc) and its not being loaded leads to unexpected behaviour. However, in many cases ng-module is an empty class and its only usage is for providing scope, and since in AoT full compilation mode we already hard-code dependencies into components so we can get away with not loading the ng-module. But in AoT local compilation mode it is not possible to get away since the component's dependencies are computed in runtime and the presence of the corresponding ng-module in the browser is needed. For this reason in this change it is forbidden to attempt to render a component without first loading its ng-module in local compilation mode and an explicit error message is created to make this situation clear. This error message can help with catching such cases when running TGP in Google.

It would be an interesting question as to whether to ban this situation in full compilation mode as well, as it is error prone and these errors are sometimes very hard to debug.

PR Close #51726
2023-09-15 10:45:38 +02:00
Matthieu Riegler
3b1c1b91a2 docs: Add Missing SSR integrity marker error doc page (#51340)
This commit adds an error doc page for error 507 : Missing SSR content integrity marker.

PR Close #51340
2023-08-14 14:39:25 -07:00
Matthieu Riegler
0a38dc3c26 refactor(core): throw an error when hydration marker is missing from DOM (#51170)
non-destructive hydration expects the DOM tree to have the same structure in both places.
With this commit, the app will throw an error if comments are stripped out by the http server (eg by some CDNs).

fixes #51160

PR Close #51170
2023-08-04 11:31:49 -04:00
Gerald Monaco
e53d4ecf4c feat(core): add afterRender and afterNextRender (#50607)
Add and expose the after*Render functions as developer preview

PR Close #50607
2023-08-01 13:02:27 -07:00
Payam Valadkhan
89c84bf2c1 test(core): update runtime error list to include deps tracker error (#50980)
The previous commits add a new runtime error code (RUNTIME_DEPS_INVALID_IMPORTED_TYPE) which needs to be added to the golden for the tests to pass.

PR Close #50980
2023-07-18 14:04:39 +00:00
Matthieu Riegler
3dafc14e84 refactor(core): Log a warning when multiple pipes match a name (#50389)
Since this might be too breaking, let's log for now and wait for a major to throw an actual error.

Fixes #13569

PR Close #50389
2023-07-11 08:29:07 -07:00
Matthieu Riegler
9afd90c59d refactor(core): Add a warning when ApplicationRef.isStable doesn't emit true (#50295)
Hydration requires a stable App to run some logic.
With this warning developers will be informed about potential issues encountered when running an unstable app.

Fixes #50285

PR Close #50295
2023-05-17 08:45:26 -07:00
Matthieu Riegler
0214739488 refactor(core): Throw an error when the document is not initialized. (#50143)
In case the document is accessed but not available we should throw ASAP an error to prevent non explicit errors.

PR Close #50143
2023-05-08 14:35:38 -07:00
Matthieu Riegler
08949c7c6c refactor(core): Error code for Component Id collision (#49986)
The commit add an error code for the Component Id collision and documentation page to fix the issue.

PR Close #49986
2023-04-26 09:19:58 -07:00
Pawel Kozlowski
2c22e6fb5f fix(core): onDestroy should be registered only on valid DestroyRef (#49804)
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
2023-04-13 21:14:44 +00:00
Andrew Scott
5c415e9dae refactor(core): Update signal signature with respect to initial values (#49769)
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
2023-04-12 09:35:55 -07:00
Andrew Kushnir
fe34de47bf refactor(core): add a warning when hydration annotation is missing in server response (#49743)
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
2023-04-07 09:41:55 -07:00
Andrew Kushnir
5bf2b7da6f refactor(core): skip hydration for components that use i18n (instead of throwing an error) (#49722)
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
2023-04-06 10:59:26 -07:00
Jessica Janiuk
4b673d5ed7 docs: Add error page for NG0504 error (#49689)
This adds a detailed error page for the hydration invalid ngSkipHydration host error.

PR Close #49689
2023-04-03 19:19:27 -07:00
Jessica Janiuk
9e9e1313a9 docs: Add error page for NG0503 error (#49689)
This adds a detailed error page for the hydration unsupported projection of DOM nodes error.

PR Close #49689
2023-04-03 19:19:26 -07:00
Jessica Janiuk
f1566f3325 docs: Add error pages for NG0501 and NG0502 errors (#49689)
This adds a detailed error pages for the hydration missing siblings and hydration missing node errors.

PR Close #49689
2023-04-03 19:19:26 -07:00
Jessica Janiuk
b7c5acb542 docs: Add error page for NG0500 hydration node mismatch error (#49689)
This adds a detailed error page for the hydration node mismatch error.

PR Close #49689
2023-04-03 19:19:26 -07:00
Andrew Scott
e9dd7f0028 refactor(core): Prevent reads and writes to signals at certain times (#49631)
* 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
2023-03-30 16:09:12 -07:00
Jessica Janiuk
0851bd5283 refactor(core): Improve hydration error handling (#49502)
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
2023-03-22 11:47:41 -07:00
Andrew Scott
4e098fa8a7 refactor(core): move Zone providers to a single provider function (#49373)
This commit moves the providers for `NgZone`-based change detection to a
single provider function. This function is currently called by default
in all places where `NgZone` was provided
(`bootstrapApplication`, `bootstrapModule`, and `TestBed`).

When we want to make Angular applications zoneless by default, we
can make a public provider method that has to be used in order to enable
the zone change detection features. When this method is not called,
Angular would use `NoopNgZone` by default and not initialize any
subscriptions to the `NgZone` stability events.

Side note: There are actually two places that `NgZone` is provided for `TestBed`
(providers in `compileTestModule` and `BrowserTestingModule`). This
likely doesn't need to be in both locations.

PR Close #49373
2023-03-14 09:20:53 -07:00
robertIsaac
c5a84851ea docs: add NG0403.md for Bootstrapped NgModule doesn't specify which component to initialize error (#48483)
- update `errors.ts` to annotate the error NG0403, so that the runtime can add a link to that guide when an error is thrown
- update `application_ref_spec.ts` to include the new link of the error
- update `errors.md` as a result of running `yarn bazel test packages/core/test`

Fixes #47985

PR Close #48483
2023-01-04 09:59:24 -08:00
Andrew Scott
ff84c73603 docs(core): Document invalid multi token (#48267)
Add error page for invalid multi token runtime error

PR Close #48267
2022-12-13 14:05:59 -08:00
Andrew Kushnir
ec8b52af69 docs(core): add an error details page for unsafe <iframe> bindings (#48027)
PR Close #48027
2022-11-11 11:28:35 -08:00
Andrew Kushnir
2d8d562604 fix(core): hardening attribute and property binding rules for <iframe> elements (#47964)
This commit updates the logic related to the attribute and property binding rules for <iframe> elements. There is a set of <iframe> attributes that may affect the behavior of an iframe and this change enforces that these attributes are only applied as static attributes, making sure that they are taken into account while creating an <iframe>.

If Angular detects that some of the security-sensitive attributes are applied as an attribute or property binding, it throws an error message, which contains the name of an attribute that is causing the problem and the name of a Component where an iframe is located.

BREAKING CHANGE:

Existing iframe usages may have security-sensitive attributes applied as an attribute or property binding in a template or via host bindings in a directive. Such usages would require an update to ensure compliance with the new stricter rules around iframe bindings.

PR Close #47964
2022-11-09 00:47:56 -08:00
Andrew Kushnir
13b863a1bf Revert "fix(core): hardening rules related to the attribute order on iframe elements (#47935)" (#47959)
This reverts commit 2d08965b1a.

The reason for revert is that we've identified some issues with implementation. The issues will get addressed soon and the fix would be re-submitted.

PR Close #47959
2022-11-03 11:20:32 -07:00
Andrew Kushnir
2d08965b1a fix(core): hardening rules related to the attribute order on iframe elements (#47935)
This commit updates the logic related to the attribute order on iframes and makes the rules more strict. There is a set of iframe attributes that may affect the behavior of an iframe, this change enforces that these attributes are applied before an `src` or `srcdoc` attributes are applied to an iframe, so that they are taken into account.

If Angular detects that some of the attributes are set after the `src` or `srcdoc`, it throws an error message, which contains the name of ann attribute that is causing the problem and the name of a Component where an iframe is located. In most cases, it should be enough to change the order of attributes in a template to move the `src` or `srcdoc` ones to the very end.

BREAKING CHANGE:

Existing iframe usages may have `src` or `srcdoc` preceding other attributes. Such usages may need to be updated to ensure compliance with the new stricter rules around iframe bindings.

PR Close #47935
2022-11-02 09:07:31 -07:00
Kristiyan Kostadinov
50f8928d56 refactor(core): add host directive definitions validation (#47589)
Adds some logic to ensure that host directives are configured correctly.

PR Close #47589
2022-09-30 10:52:12 -07:00
Andrew Kushnir
66e41223f3 refactor(core): improve an error message when ENVIRONMENT_INITIALIZER is not a multi provider (#46829)
Currently if the `ENVIRONMENT_INITIALIZER` token is not configured with `multi: true` flag, the code fails while trying to iterate over the value. This commit checks whether the `ENVIRONMENT_INITIALIZER` token value type is an array and throws a helpful error message.

PR Close #46829
2022-07-13 22:01:14 +00:00
Alex Rickabaugh
af600cd2b7 refactor(core): disable automatic usage of Renderer3 (#46605)
Previously, when instantiating a component, Angular would look in the DI
hierarchy for `RendererFactory2`. Any DI tree which rolls up through an
application injector (that is, one created with `BrowserModule`) should be
able to provide this interface. If not found, Angular would switch to the
experimental `Renderer3` mechanism. This switch was designed this way,
because it allowed for the creation of experimental applications where
`RendererFactory2` was not included in the bundle at all.

In this commit, instead of automatically falling back on `Renderer3`-style
rendering, an error is raised instead if `RendererFactory2` is missing from
the DI hierarchy.

PR Close #46605
2022-06-30 09:04:56 -07:00
Ramesh Thiruchelvam
07828528be refactor(core): make di error messages tree shakable (#46422)
Tree shake error messages from the production build and introduce error codes.

PR Close #46422
2022-06-24 13:12:21 -07:00
Ramesh Thiruchelvam
7da389a461 refactor(core): make zone error messages tree shakable (#46480)
Make the error messages tree shakable from the production build to reduce the bundle size.

PR Close #46480
2022-06-24 13:11:14 -07:00
Ramesh Thiruchelvam
1da3a051b5 refactor(core): make i18n error messages tree shakable (#46468)
Make the error messages tree shakable from the production build to reduce the bundle size.

PR Close #46468
2022-06-23 16:36:35 -07:00
Pawel Kozlowski
12b4ec3d85 docs: create a dedicated page for the NG0203 error (#46166)
Adds a dedicated error page for NG0203 (injection context).

PR Close #46166
2022-05-27 10:15:55 -07:00
Pawel Kozlowski
410d81f0e2 refactor(core): disallow standalone components in importProvidersFrom calls (#45837)
This commit narrows down acceptable argument types of the
`importProvidersFrom` function. More specifically, it rejects
standalone components as a source of imports.

PR Close #45837
2022-05-03 13:12:36 -07:00
Alex Rickabaugh
d322052db3 refactor(core): guard against importProvidersFrom in components (#45838)
`importProvidersFrom` provides a bridge from the world of NgModule-based DI
configuration to the new, "standalone" world of direct providers and
environment injectors. Early user feedback suggested some confusion around
where this function was supposed to be used, particularly around importing
NgModule-based providers into standalone component `providers` arrays, which
is not the intended use. This confusion is exacerbated by the fact that due
to the unified `Provider` type, this kind of misconfiguration was happily
accepted by the type system.

This commit changes the return type of `importProvidersFrom` to wrap the
returned providers in an opaque type that prevents them from being used in
component provider contexts. This, together with stronger documentation
around the purpose and functionality of `importProvidersFrom`, should
address some of the above confusion.

PR Close #45838
2022-05-02 15:50:44 -07:00
Andrew Kushnir
5771b18a98 feat(core): add the bootstrapApplication function (#45674)
This commit implements the `bootstrapApplication` function that allows bootstrapping an application and pass a standalone component as a root component.

PR Close #45674
2022-04-21 17:47:54 -07:00
Andrew Kushnir
174ce7dd13 feat(core): add ApplicationRef.destroy method (#45624)
This commit implements the `destroy` method on the `ApplicationRef` class. This feature is a preparation for the new logic to bootstrap (and teardown) standalone components (without going through the `NgModuleRef` destroy), which would return an instance of the `ApplicationRef` (the current bootstrap APIs return an instance of the `NgModuleRef`).

PR Close #45624
2022-04-18 14:09:47 -07:00
Andrew Kushnir
ed1732c268 refactor(core): the RuntimeError class should support more compact syntax (#44783)
This commit refactors the `RuntimeError` class to support a short version of providing error messages:
```
throw new RuntimeError(
  RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
  ngDevMode && 'Injector has already been destroyed.');
```
In prod mode, the second argument becomes `false` andn this commit extends the typings to support that.

This commit also contains a couple places were the `RuntimeError` class is used to demostrate the compact form.

PR Close #44783
2022-02-01 00:15:56 +00:00