Reputation: 315
I have a problem with angular 17 signal effect. I try to reset a form in the effect when the facilities signal is updated.
I have this message error in the browser console:
NG0600: Writing to signals is not allowed in a
computed
or aneffect
by default. UseallowSignalWrites
in theCreateEffectOptions
to enable this inside effects.
If I remove from the effect the this_form. Reset, no error in the console. If I add the effect option to allowSignalWrites it works, but I don't understand why as I don't write a signal, I just reset a form.
formResetEffect = effect(() => {
if (this.facilities()) {
this._form.reset({
disabled: false,
value: null
});
}}, {allowSignalWrites: true});
Could you help me to understand this behavior?
Thanks
UPDATE:
It appears that the issue appear only when I use the p-dropdown component from PrimeNG. I've examined the code of the p-dropdown in the GitHub repository, and this component now uses signals.
Do you think the signal writing into the p-dropdown component could be the cause of the problem?
Here a stackblitz to reproduce the problem: stackblitz
Upvotes: 3
Views: 5883
Reputation: 550
Do you think the signal writing into the p-dropdown component could be the cause of the problem?
Yes. At least from my understanding. effect()
works as intended.
Why?
effect()
(as well as computed()
) magically check deep down all function-calls if there is a any interaction with signals. Even if it's "hidden" in some functions.
I assume that FormGroup.reset()
calls Dropdown()
which triggers the set()
of signals (see line 861-865 of primeng dropdown github).
Imagine it likes this:
- effect() // ✅ no signals
-- FormGroup.reset() // ✅ no signals
--- Dropdown() // ❌ calls "set()" of signals
Here as a example which makes it clear:
mySignal = signal("");
effReturn = effect(()=>{
this.method1();
}); // ❌ throws NG0600 without {allowSignalWrites: true}
method1(): void {
this.method2();
}
method2(): void {
mySignal.set("hello world");
}
So, again: effect()
works as intended and allowSignalWrites
flag has to be set here.
Some could ask now: why isn't allowSignalWrites
flag set to true by default in the first place?
What I think: angular-devs want to (a) manual signal-sets as small as possible (rather use computed()
to calculate signals) because (b) signals-sets will decrease readability your code.
In other words: calling set()
within effect()
should be the exception!
Anyways, in your example I think it's totally fine using effect()
with allowSignalsWrites
.
By the way:
The if-condition of the dropdown-basic-demo.ts:25
in your stackblitz-example is obsolete. cities()
is always set per definition.
Upvotes: 3