You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tl;dr: we're in awe of the passion and engagement our community brought to this RFC - and signals are go for launch 馃殌
Firstly, we would like to extend our gratitude and appreciation to our community, especially those who put their time and energy into reading our multi-document RFC for Angular Signals and sharing their thoughts and experiences with us. This RFC generated a record 1,000+ comments, nearly double that of every previous RFC combined, and the resulting technical discussions have been deeply informative. We're both amazed and deeply appreciative of this level of engagement - thank you 鉂わ笍
Even during the first week, we saw clear indications in your responses that certain aspects of the design would need revisiting, and applied some early updates. A few of the more impactful changes were:
Rolling back more aggressive changes to component lifecycle methods, and better presenting afterRender as an application level API.
Renaming the interop APIs to follow a toSignal rather than fromObservable naming pattern.
Adjusting semantics in a few APIs to move away from runtime errors by default.
Adding asReadonly to the WritableSignal interface.
To close out the RFC, let's first cover the direct discussion questions which we posed.
Discussion questions
From Sub-RFC 1: Signals for Angular Reactivity
1A: are there other requirements we should consider?
None of the comments presented what we would consider new technical requirements, although we took note of concern around the dangers of having multiple reactivity systems in the learning journey. We'll cover this more later.
From Sub-RFC 2: Signal APIs
2A: given the trade-offs outlined here, would you prefer the Signal / WritableSignal naming pair or the ReadonlySignal / Signal one?
We saw roughly similar sentiment for both naming patterns. Given no clear and obvious preference by the community, we're going to with what we feel is the "safer" API and split them as Signal / WritableSignal.
2B: is the convenience of the .update worth introducing, given the larger public API surface?
Overwhelmingly, respondents to this question felt that .update() provided a lot of value, so we'll keep it.
2C: in some systems (e.g. Vue) reactive state is inherently mutable throughout the application. In other frameworks (e.g. SolidJS) this separation is enforced even more strongly. What do you think about our choice to separate readers and writers, and the architectural benefits or drawbacks of this approach?
Most commenters who addressed this question felt like the separation of readability from mutability makes architectural sense, and we agree.
2D: Do the potential advantages of .value outweigh the disadvantages? Would you prefer that API?
Similarly to 2A, the Angular community seems to have roughly equal preference for signal getters compared to.value as the read API. Despite clear preferences, we felt that none of the arguments presented new information which would invalidate our own accounting of the tradeoffs here, and have decided to proceed with the getter function APIs. We do note that this is contingent on us achieving a satisfactory developer experience with template type-checking, and will revisit this decision if our hypothetical solutions to this problem turn out to fail in practice.
From Sub-RFC 3: Signal-based components:
3A: We're actively looking for feedback on the developer experience of this behavior (view-level granularity and reading non-signal values in templates)
There was some discussion of this behavior as surprising, and whether Angular could provide safety checks to detect or prevent depending on values that change outside of signals. This is something we'll be looking into.
3B: Should signal-based components introduce a new syntax for two-way bindings?
Another case of roughly split responses. We will move forward with the existing two-way binding syntax to reduce churn.
3D: We're interested in hearing opinions on the developer experience of this API (input())
The input() APIs generated some controversy! In fact, one of the first updates to the RFC was to clarify the section on signal-based inputs, since several of the initial comments indicated that the API was very poorly described.
In general, we saw feedback around a few points:
Not using member decorators for @Input & others
input() functions being treated specially by the compiler
Alternatives to the options object, such as a builder pattern
Why not @Input() x = signal(...)?
We've been active in many of these discussions, so we won't copy them here. In conclusion though, we feel like the API as proposed (and subsequently clarified) offers the best developer experience of all discussed options.
From Sub-RFC 4: Observable and Signal Interoperability
4A: Feedback on the behavior of fromObservable and initial value
This discussion question was actually deleted in the round of updates after the first week, as it was settled by the update. In response to your feedback, we adjusted the design of toSignal (previously fromObservable) to not throw runtime errors by default for non-synchronous Observables. Instead, it returns an undefined value/type unless an initial value is specified. To handle the case of known-synchronous Observables, we added a requireSync flag which can be specified to remove the undefined from the type, on the condition that the Observable emits synchronously. If it does not, then toSignal throws immediately, instead of waiting until you call the getter.
Additional Feedback
In addition to the explicit discussion questions, we received invaluable feedback on many other aspects of the design. Even a summary of the 1,000+ comments would be too long to share here, but here are a few highlights:
On having two reactivity systems
We received a lot of feedback (and largely agree) that having both signal and zone reactivity in Angular creates the potential for confusion going forwards, and that the Angular team needs to have clear and unambiguous messaging on the preferred way to write components. We will keep this in mind as we consider the impact signals have on our documentation and learning journey. It's deeply important to us (and clearly from the feedback, important to our community as well) that we maintain our opinionated nature here.
Commitment to backwards compatibility
Throughout the discussion, we've re-affirmed our commitment to supporting zone-based components for the foreseeable future. Although our clear hope is that the signals experience is universally preferred for authoring Angular code in the near future, we recognize that zone-based change detection will continue to be the backbone of many applications for a long time. We hope the scope and scale of these RFCs shows the level of thoughtfulness we're putting into evolving Angular to be ready for the next 10 years of web development, while not leaving the applications of today behind.
Effects seem easy to misuse
Many comments focused on the effect() API and its various uses. A common thread among these discussions was how easily effects, as a very low level API, could be misused in ways that could create problems down the road. Where possible, we will attempt to put up good guardrails (such as preventing writing to signals directly in effects by default), or apply other tools we have (language service, documentation, etc) to promote good patterns for effects and discourage anti-patterns.
On future authoring format changes
In the RFC we mentioned the use of non-decorator APIs as being compatible with potential changes to the authoring format for Angular. This spawned several discussion threads expressing concern about the direction of such changes.
Currently, we have no concrete designs for authoring format changes. What we do know is that there are several aspects of the existing experience that we know we want to improve. Notable items on the list include:
The need to double-import dependencies in standalone components.
Not being able to use imported functions or enums directly in templates.
Templates not being able to use the full TypeScript expression language.
Several parts of template syntax predating equivalent ECMAScript features and having different semantics (e.g. optional chaining).
We plan to explore ways to address these issues in a future project, but for now our attention is focused on the updates to reactivity. When we do have a better idea of what an improved authoring experience might look like, you can expect a similarly transparent RFC process.
Future RFCs
In some of the discussions, certain topics have come up which are big enough that they deserve their own focused RFCs. Two of these which we've identified thus far are:
Testing with Signals
Control Flow
So stay tuned 馃摗 we'll be posting followup RFCs on these and maybe more topics in the coming months.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Angular Signals RFC - Closing Summary
Tl;dr: we're in awe of the passion and engagement our community brought to this RFC - and signals are go for launch 馃殌
Firstly, we would like to extend our gratitude and appreciation to our community, especially those who put their time and energy into reading our multi-document RFC for Angular Signals and sharing their thoughts and experiences with us. This RFC generated a record 1,000+ comments, nearly double that of every previous RFC combined, and the resulting technical discussions have been deeply informative. We're both amazed and deeply appreciative of this level of engagement - thank you 鉂わ笍
Even during the first week, we saw clear indications in your responses that certain aspects of the design would need revisiting, and applied some early updates. A few of the more impactful changes were:
afterRender
as an application level API.toSignal
rather thanfromObservable
naming pattern.asReadonly
to theWritableSignal
interface.To close out the RFC, let's first cover the direct discussion questions which we posed.
Discussion questions
From Sub-RFC 1: Signals for Angular Reactivity
None of the comments presented what we would consider new technical requirements, although we took note of concern around the dangers of having multiple reactivity systems in the learning journey. We'll cover this more later.
From Sub-RFC 2: Signal APIs
We saw roughly similar sentiment for both naming patterns. Given no clear and obvious preference by the community, we're going to with what we feel is the "safer" API and split them as
Signal
/WritableSignal
.Overwhelmingly, respondents to this question felt that
.update()
provided a lot of value, so we'll keep it.Most commenters who addressed this question felt like the separation of readability from mutability makes architectural sense, and we agree.
Similarly to 2A, the Angular community seems to have roughly equal preference for signal getters compared to
.value
as the read API. Despite clear preferences, we felt that none of the arguments presented new information which would invalidate our own accounting of the tradeoffs here, and have decided to proceed with the getter function APIs. We do note that this is contingent on us achieving a satisfactory developer experience with template type-checking, and will revisit this decision if our hypothetical solutions to this problem turn out to fail in practice.From Sub-RFC 3: Signal-based components:
There was some discussion of this behavior as surprising, and whether Angular could provide safety checks to detect or prevent depending on values that change outside of signals. This is something we'll be looking into.
Another case of roughly split responses. We will move forward with the existing two-way binding syntax to reduce churn.
The
input()
APIs generated some controversy! In fact, one of the first updates to the RFC was to clarify the section on signal-based inputs, since several of the initial comments indicated that the API was very poorly described.In general, we saw feedback around a few points:
@Input
& othersinput()
functions being treated specially by the compiler@Input() x = signal(...)
?We've been active in many of these discussions, so we won't copy them here. In conclusion though, we feel like the API as proposed (and subsequently clarified) offers the best developer experience of all discussed options.
From Sub-RFC 4: Observable and Signal Interoperability
This discussion question was actually deleted in the round of updates after the first week, as it was settled by the update. In response to your feedback, we adjusted the design of
toSignal
(previouslyfromObservable
) to not throw runtime errors by default for non-synchronous Observables. Instead, it returns anundefined
value/type unless an initial value is specified. To handle the case of known-synchronous Observables, we added arequireSync
flag which can be specified to remove theundefined
from the type, on the condition that the Observable emits synchronously. If it does not, thentoSignal
throws immediately, instead of waiting until you call the getter.Additional Feedback
In addition to the explicit discussion questions, we received invaluable feedback on many other aspects of the design. Even a summary of the 1,000+ comments would be too long to share here, but here are a few highlights:
On having two reactivity systems
We received a lot of feedback (and largely agree) that having both signal and zone reactivity in Angular creates the potential for confusion going forwards, and that the Angular team needs to have clear and unambiguous messaging on the preferred way to write components. We will keep this in mind as we consider the impact signals have on our documentation and learning journey. It's deeply important to us (and clearly from the feedback, important to our community as well) that we maintain our opinionated nature here.
Commitment to backwards compatibility
Throughout the discussion, we've re-affirmed our commitment to supporting zone-based components for the foreseeable future. Although our clear hope is that the signals experience is universally preferred for authoring Angular code in the near future, we recognize that zone-based change detection will continue to be the backbone of many applications for a long time. We hope the scope and scale of these RFCs shows the level of thoughtfulness we're putting into evolving Angular to be ready for the next 10 years of web development, while not leaving the applications of today behind.
Effects seem easy to misuse
Many comments focused on the
effect()
API and its various uses. A common thread among these discussions was how easily effects, as a very low level API, could be misused in ways that could create problems down the road. Where possible, we will attempt to put up good guardrails (such as preventing writing to signals directly in effects by default), or apply other tools we have (language service, documentation, etc) to promote good patterns for effects and discourage anti-patterns.On future authoring format changes
In the RFC we mentioned the use of non-decorator APIs as being compatible with potential changes to the authoring format for Angular. This spawned several discussion threads expressing concern about the direction of such changes.
Currently, we have no concrete designs for authoring format changes. What we do know is that there are several aspects of the existing experience that we know we want to improve. Notable items on the list include:
We plan to explore ways to address these issues in a future project, but for now our attention is focused on the updates to reactivity. When we do have a better idea of what an improved authoring experience might look like, you can expect a similarly transparent RFC process.
Future RFCs
In some of the discussions, certain topics have come up which are big enough that they deserve their own focused RFCs. Two of these which we've identified thus far are:
So stay tuned 馃摗 we'll be posting followup RFCs on these and maybe more topics in the coming months.
Beta Was this translation helpful? Give feedback.
All reactions