Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling observer.next() on Observable<void> in RxJS

Tags:

angular

rxjs

I am creating a module that uses RxJS Observable and some of the methods are returning Observable<void>. I have searched around quite a bit now, but can't find any best practices on completion of Observable<void>.

So the question is simple, should the next callback be issued for these observables, or just the complete callback?

In my opinion it seems to be cleanest to only call complete, but Observable<T>.subscribe() has complete as it last parameter, which makes it more complicated for users to use.

Take this code example as an illustration of the question:

doSomethingIgnorableUnlessError(): Observable<void> {
  return Observable.create((observer: Observer<void>) => {
    if (executeIgnorable()) {
      // should observer.next(null); be called here?
      observer.next(null); 
      observer.complete();
    } else {
      observer.error('something that shouldn't be ignored occurred');
    }
  }
}
like image 703
Rune G Avatar asked Jul 12 '18 20:07

Rune G


Video Answer


1 Answers

Personally, my approach is that if you have Observable<void> it means it emits but its values don't matter. You can still call next() but to make it obvious that you're not passing any value you should use void 0:

subject.next(void 0);

Then consuming this Subject is like any other Observable where you just ignore the value itself:

subject.subscribe(() => ...);

What's important here is that this is not the same as using null or undefined. You can have for example Observable<number> and call observer.next(null) or observer.next(undefined) (https://stackblitz.com/edit/rxjs6-demo-jtwymx?file=index.ts) even though it doesn't make sense. You want a number but if you receive undefined you might experience weird behavior. For example undefined + 4 is NaN.

I think a typical use-case for Observable<void> is infinite scroll. When you scroll to the end of a page you want to load more data so you call subject.next(void 0) where it's obvious that the value doesn't matter. It's only used to trigger loading more items.

like image 153
martin Avatar answered Oct 10 '22 14:10

martin