angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
95.74k stars 25.27k forks source link

Signal Equality and mutable changes #53139

Closed rainerhahnekamp closed 10 months ago

rainerhahnekamp commented 10 months ago

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

Angular ignores a customized equal function in a Signal when the object reference is the same. @alxhub explained the reasons in https://github.com/angular/angular/issues/52176#issuecomment-1769099075

I have a potential real-world example: https://stackblitz.com/edit/stackblitz-starters-lushjx?file=src%2Fmain.ts, where this causes real issues. I see currently no way how to force a signal to emit on mutable changes.

I would kindly ask you to reconsider removing the short-circuit introduced in https://github.com/angular/angular/pull/52465.

If not, I could provide a PR that explains that behavior in the documentation.

Proposed solution

Run customized equality check even if object reference is the same.

Alternatives considered

Update the documentation with a proper explanation: https://angular.dev/guide/signals#signal-equality-functions

dmorosinotto commented 10 months ago

Even I don’t get the point of having a custom equalityFn if it’s ignored by the short-circuit logic that evaluate it only if !Object.is

In my mind (and before the change introduced in #52465 ) the role of equal function was to tell signals how to compare two values (indipendent of their mutable or immutable nature) so the devs take responsibility of return true/false based on their needs.

I don’t fully understood the motivation of @alxhub in #52176 comment where he stated that equal(x,x) must always return true if Object.is(x,x)==true otherwise we have a change detection problem in template setting input !?

In my mind (and maybe over semplificating it) the template render is “like an effect” that is re-evaluated (render) each times a signal notify a change, and this mechanism involve the equal function to decide when to propagate “real or wanting” value changes…

I admit that I have NOT enough understanding of the deep template rendering mechanics of Angular so maybe my previous statement is over semplificate and totally un-realistic , but I’d really like to have and use signal as a reactive primitive and have a choise to control it’s “internal value-change detection” check via my custom equalityFn in all cases if possible!

So I’m pro 👍 to ask reverting the Object.is short-circuit, or really clarify the docs as asked by @rainerhahnekamp explaining the correct mental model we have to assume when thinking on equal and signal propagation -> change detection / render 🙏

atscott commented 10 months ago

Duplicate of https://github.com/angular/angular/issues/52735

mikezks commented 10 months ago

The current behavior does not make sense.

Either one is not allowed to create specific equal functions (in this case for same object references with result false), then we need to throw an error and ignore the equal function.

Or the warning is logged to the console, but then the equal function needs to be used even if not recommended.

Showing a warning only, but ignoring the equal function is not an expectable behavior.

mikezks commented 10 months ago

@dmorosinotto, I understand that the Angular team cannot support change detection scenarios based on mutable Signal updates. TBH, I was surprised that they tried to support mutable updates at the beginning, because the necessary value comparisons come with some runtime costs.

But the current implementation is not intuitive as described above.

angular-automatic-lock-bot[bot] commented 9 months ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.