angular / angular

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

signal(Observable<T>) to signal<T>() operator #55675

Closed MGX-CODING closed 5 months ago

MGX-CODING commented 6 months ago

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

core

Description

Here is a quick example of the requested feature (of course it has no value in itself) :

  $control = signal(new FormControl(''));

  $valueChanges$ = computed(() => this.$control().valueChanges);

  valueChanges$ = toObservable(this.$valueChanges$).pipe(switchMap((v) => v));

  $valueChanges = toSignal(this.valueChanges$);

STACKBLITZ

Proposed solution

  $control = signal(new FormControl(''));
  $valueChanges = transmuted(() => this.$control().valueChanges);

Alternatives considered

The code of the example itself.

This is not the first time I have the need for something like this, and as far as I'm aware, there is no easy way to do something similar (please correct me if I'm wrong)

jnizet commented 6 months ago

I personally find using toSignal() and toObservable() perfectly reasonable here since you precisely want to transform a signal to an observable and vice-versa.

The code could be simplified to

const control = signal(new FormControl(''));
const value = toSignal(toObservable(control).pipe(switchMap(c => c.valueChanges)));
MGX-CODING commented 6 months ago

I personally find using toSignal() and toObservable() perfectly reasonable here since you precisely want to transform a signal to an observable and vice-versa.

The code could be simplified to

const control = signal(new FormControl(''));
const value = toSignal(toObservable(control).pipe(switchMap(c => c.valueChanges)));

It is indeed clearer, thank you for that, but still, don't you think it looks complicated ?

jnizet commented 6 months ago

No. It's very explicit.

MGX-CODING commented 6 months ago

Well on that we agree, maybe I should have said concise then ... Can this issue remain open, just to have more opinions ?

(Thanks again for the more concise way !)

kbrilla commented 6 months ago

@MGX-CODING mayby this will cover Your needs https://ngxtension.netlify.app/utilities/signals/derived-async/

it will look like this:

  $control = signal(new FormControl(''));
  $valueChanges = derivedAsync(() => $control().valueChanges);
JoostK commented 5 months ago

We were discussing just now and our interpretation is that 1) this particular case is because the forms API does not provide a signal for the current value, and 2) that it's more appropriate to convert to RxJS earlier in this case to avoid the awkward switchMap transform:

  $valueChanges = toSignal(toObservable(this.$control).pipe(
    switchMap(control => control.valueChanges),
  ));

That has the same output type.

We don't otherwise see the need for a flattening operator from Signal<Observable<T>> to Signal<T>.

MGX-CODING commented 5 months ago

Just so we're clear, this was one example amongst others, this is not related to form controls in any way, shape or form.

But thank you for the feedback on the proposition still, much appreciated !

angular-automatic-lock-bot[bot] commented 4 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.