1

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?

Ole
  • 41,793
  • 59
  • 191
  • 359

1 Answers1

2

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)
  );
}
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • thanks that makes a lot more sense :). I'm getting a different error now: [ts] Argument of type 'OperatorFunction' is not assignable to parameter of type 'OperatorFunction'. Type 'boolean | E[]' is not assignable to type 'E[]'. Type 'false' is not assignable to type 'E[]'. Any ideas? – Ole Sep 19 '18 at 22:39
  • 1
    Yeah, you'll want to do `startWith(values(this.entries))` instead. That way `map` is always mapping `E[]` items. As it currently is, you're starting with a boolean, which is why the type `boolean | E[]` instead of `E[]`. – Jacob Sep 19 '18 at 22:47
  • OK COOL! I ended up nuking the startWith, since the `entries` will have length zero by default on startup. Thanks again! – Ole Sep 19 '18 at 22:56
  • Slice stores now have observable count and empty notification: https://www.npmjs.com/package/@fireflysemantics/slice – Ole Sep 20 '18 at 01:04