Search code examples
angularrxjsbehaviorsubjectrxjs-observables

combineLatest with BehaviourSubject.asObservable causing stream was expected error


I'm trying to use combineLatest with a BehaviourSubject.asObservable but getting this error:

TypeError: You provided 'function () {
        return this.ctaButtonSpinnerTriggered.asObservable();
    }' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
private ctaButtonSpinnerTriggered: BehaviorSubject<
    boolean
> = new BehaviorSubject(false);

public isCtaButtonSpinnerTriggered(): Observable<boolean> {
    return this.ctaButtonSpinnerTriggered.asObservable();
}

public setCtaButtonSpinnerTriggered(isDisabled: boolean): void {
    this.ctaButtonSpinnerTriggered.next(isDisabled);
}

public get showCtaSpinner(): Observable<boolean> {
    return combineLatest([
        this.ctaDisabled,
        this.isCtaButtonSpinnerTriggered,
    ]).pipe(
        map(
            ([ctaDisabled, isCtaButtonSpinnerTriggered]: [
                boolean,
                boolean
            ]) => {
                console.log(
                    !ctaDisabled,
                    isCtaButtonSpinnerTriggered,
                    'ctaDisabled + isCtaButtonSpinnerTriggered'
                );
                return !ctaDisabled && isCtaButtonSpinnerTriggered;
            }
        )
    );
}

Any ideas what would be the right implementation of combineLatest with BehaviourSubject ?


Solution

  • Change

    return combineLatest([
            this.ctaDisabled,
            this.isCtaButtonSpinnerTriggered,
        ])
    

    to

    return combineLatest([
            this.ctaDisabled,
            this.isCtaButtonSpinnerTriggered(), // note the parentheses here
        ])
    

    because it's not a getter function.


    To make your property as getter/setter change them to:

    private ctaButtonSpinnerTriggered: BehaviorSubject<
        boolean
    > = new BehaviorSubject(false);
    
    public get isCtaButtonSpinnerTriggered(): Observable<boolean> {
        return this.ctaButtonSpinnerTriggered.asObservable();
    }
    
    public set isCtaButtonSpinnerTriggered(isDisabled: boolean): void {
        this.ctaButtonSpinnerTriggered.next(isDisabled);
    }
    

    and use it as

    return combineLatest([
            this.ctaDisabled,
            this.isCtaButtonSpinnerTriggered,
        ])