Search code examples
javascriptangulartypescriptrxjsswitchmap

Emitting a hot boolean observable using switchMap?


Trying to create an isEmpty:Observable<boolean>method that emits a hot Observable<boolean> using a switchMap. This is what I have so far:

  /**
   * Notifies observers when the store is empty.
   */
  protected notifyOnEmpty = new ReplaySubject<E[]>(1);

  /**
   * Check whether the store is empty.
   * 
   * @return A hot {@link Observable<boolean>} that indicates whether the store is empty.
   * 
   * @example
     <pre>
    source.isEmpty();
    </pre>
  */
  isEmpty<E>():Observable<boolean> {
    const isCurrentlyEmpty = values(this.entries).length == 0;
    return this.notifyOnEmpty.pipe(startWith(isCurrentlyEmpty), 
                                   switchMap((entries:E[])=>entries.length == 0));
  }

The thinking is that the store can then call notifyOnEmpty.next(Object.values(this.entries)) to let subscribers know whether the store is empty.

Anyways the switchMap statement leads to the error:

[ts] Argument of type '(entries: E[]) => boolean' is not assignable to parameter of type '(value: E[], index: number) => ObservableInput'. Type 'boolean' is not assignable to type 'ObservableInput'. (parameter) entries: E[]

Thoughts?


Solution

  • The switchMap operator is used to select a new observable on each value. You only need a regular map so that each Array is mapped to a boolean:

    import { map, startWith } from 'rxjs/operators';
    
    // ...
    
    isEmpty<E>():Observable<boolean> {
      return this.notifyOnEmpty.pipe(
        startWith(values(this.entries)), 
        map((entries:E[]) => entries.length == 0)
      );
    }