Search code examples
rxjs6

RxJS operator to subscribe to a new source only if the first source is empty?


I'm trying to figure out how - using RxJS 6 - to check a cache for a value and only if the value isn't found in the cache, request the value from the database. Ideally, I'd then be able to add the value received from the DB to the cache.

So far, I've looked at race, but that's going to request both and take whichever responds first. I don't want to request from the DB if the value is available in cache. flatMap seems to have the same issue?

I'm aware of defaultIfEmpty but that only provides a default value, not subscribe to a new Observable and emit those values instead.


Solution

  • I think the operator you are looking for here is defer, which won't actually create the observable being subscribed to until subscription time, according to the factory creation function. You haven't posted code, but in pseudo code form it would look something like this:

    const getValue$ = (value: number) => defer(() => {
        const cachedValue = checkCache(value);
        if (cachedValue) {
            return of(cachedValue);
        } else {
            return this.db.get(value).pipe(
                mergeMap(dbReturnedValue => addToCache(dbReturnedValue))
            );
        }
    });
    
    // later in code:
    getValue$(testValue).subscribe(
        data => doSomething(data),
        err => processError(err)
    );