angular: Signals: Writing to signals is not allowed in a `computed`

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

I believe there is a bug in creating computed signal from method returning observable:

 constructor(private injector: Injector) {}
  userId: Signal<string> = signal('userA');
  roles = computed(() =>
    toSignal(getRoles(this.userId()), { injector: this.injector })()
  );

//this could be api service sending  http request
const getRoles = (userId: string) => {
  return userId === 'userA' ? of([1, 2, 3]) : of([1]);
};

This code throws runtime console error Error: NG0600: Writing to signals is not allowed in a computedor aneffectby default. UseallowSignalWritesin theCreateEffectOptions to enable this inside effects.

However, that does not seem to be case of writing to signal. I read signal userId and I convert observable into signal via toSignal() method. No writing anywhere. Am I wrong?

Stackblitz here

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-admqds?file=src/main.ts

Please provide the exception or error you saw

Error: NG0600: Writing to signals is not allowed in a `computed` or an `effect` by default. Use `allowSignalWrites` in the `CreateEffectOptions` to enable this inside effects.

Please provide the environment you discovered this bug in (run ng version)

Angular 16
Nodejs 18.10

Anything else?

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 18 (8 by maintainers)

Most upvoted comments

subscriptions are piling up (who is going to unsubsribe?)

isn’t that what toSignal does automatically?

By default, the subscription will be automatically cleaned up when the current injection context is destroyed. 

From what you say I’m getting the impression that signals aren’t meant to work with async code. So going back to observables would be better idea? like

roles$ = toObservable(this.userId()).pipe(
   switchMap(userId => getRoles(userId))
)