Victor Mukherjee
Victor Mukherjee

Reputation: 11065

Rxjs: Execute code and emit value on completion of Observable

How can I execute some code and emit a final value when an Observable completes?

RxJS provides an endWith operator, which takes a value to emit on completion. I however want to pass in a valueProvider function, which should only be executed when my src$ Observable completes returning a final value that should be emitted.

const mapped$ = src$.pipe(
 //only on completion
  endWithCallback(() => {
   const endParam= this.getSomething();
   return endValue;
  }),
);

Off course, the above code does not work. How can I achieve something like this?

Upvotes: 1

Views: 1696

Answers (1)

frido
frido

Reputation: 14139

Use concat and defer to append an Observable to your source whose inner code is executed after the source completes.

concat(src$, defer(() => of(getLast())))

You could also create an operator that does it.

src$.pipe(withLast(getLast))

// 1. emits the same type as source
export function withLast<T>(getLast: () => T): MonoTypeOperatorFunction<T> {
  return (source: Observable<T>) => concat(source, defer(() => of(getLast())));
}

// 2. emits a different type than source
export function withLastAs<T, R>(getLast: () => R): OperatorFunction<T, R> {
  return (source: Observable<T>) => source.lift.call(
    concat(source, defer(() => of(getLast())))
  );
}

getLast includes the code you want to execute when your source completes and returns a value that will be emitted last.

function getLast(): any {
  console.log('on last');
  const endParam = this.getSomething();
  return endValue;
}

Upvotes: 3

Related Questions