Home > Enterprise >  Angular Subcriber for BehaviorSubject fires multiple times
Angular Subcriber for BehaviorSubject fires multiple times

Time:09-02

When calling the patchPreview method the subscriber fires multiple times. The latestAddress$ variable is a BehaviorSubject. I tried adding .pipe(...,take(1)), however this prevents the address from being updated. How can I reduce the number of subscriber calls?

protected patchPreview = (offer: Offer) => {
    
        this.geolocationService.latestAddress$
            .pipe(
                takeUntil(this.onDestroy$),
                filter(value => value !== null)
            ).subscribe((address) => {
                console.log('called more than once');
                ...
                this.offerPreview = { /*sets address */ };
            });

        this.cdr.markForCheck();
}

CodePudding user response:

The Observable emits multiple times so it's normal for your subscriber to be fired multiple times.

You could look into using throttleTime which allows you to throttle the Observable emission speed to the interval you set.

CodePudding user response:

You can use debounceTime it will reduce the number of multiple emits.

protected patchPreview = (offer: Offer) => {
    
        this.geolocationService.latestAddress$
            .pipe(
                debounceTime(1000), // 1 second debounce time
                takeUntil(this.onDestroy$),
                filter(value => value !== null)
            ).subscribe((address) => {
                console.log('called more than once');
                ...
                this.offerPreview = { /*sets address */ };
            });

        this.cdr.markForCheck();
}

CodePudding user response:

You should inspect observable latestAddress$ for multiple emissions. But it's absolutely normal for observable to emit multiple times.

Also with each function patchPreview call you make another subscription without completing the previous and every latestAddress$ emission will call subscriber as many times as function patchPreview has been run.

btw, changeDetector should markForCheck every time a value is emitted, not when the operator chain is set up and subscribed.

.subscribe((address) => {
            console.log('called more than once');
            ...
            this.offerPreview = { /*sets address */ };
            this.cdr.markForCheck();
        });
  • Related