Skip to content

new function for signal/rxjs interop #57946

@ymajoros

Description

@ymajoros

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

@angular/core

Description

I propose some function to run some computation that returns an Observable, and convert it to a signal.

Typical workflow:

  • inputs = signals
  • when they change, run some computation (typically, http requests)
  • convert to a signal

Proposed solution

export function computedFromObservable<T>(computation: () => Observable<T>, options?: CreateComputedOptions<Observable<T>>): Signal<T | undefined> {
  const computedSignal = computed(computation, options);
  const computedObservable = toObservable(computedSignal);
  const observable = computedObservable.pipe(
    switchAll()
  );
  return toSignal(observable);
}

which can be used this way:

    this.productPage = computedFromObservable(() => this.productService.find$(this.productSearch(), this.pagination()));

... replacing this more complicated construct:

    const productParams: Signal<[ProductSearch, Pagination]> = computed(() => [this.preparationSearch(), this.pagination()]);
    const productPageObservable = toObservable(productParams).pipe(
      switchMap(([productSearch, pagination]) => this.productService.find$(productSearch, pagination))
    );
    this.productPage = toSignal(productPageObservable);

Alternatives considered

Originally, I something like this, but it lacked the power of computed() (single signal as input often requiring to create an additional computed() signal anyway, not as lazy, ...):

export function pipeSignalWithDefault<T, U>(signal: Signal<T>, pipe: OperatorFunction<T, U>, initialValue: U): Signal<U> {
  const signalAsObservable = toObservable(signal);
  const signalPipe = signalAsObservable.pipe(pipe);

  return toSignal(signalPipe, {initialValue});
}

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions