Reputation: 9184
I have such service/state:
export class SpinnerService {
public throttleTime: number = 10;
public isLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
constructor() {}
public showLoader(): void {
this.isLoading$.next(true);
}
public hideLoader(): void {
this.isLoading$.next(false);
}
public get isLoadingAPIVal$(): Observable<boolean> {
return this.isLoading$.pipe(throttleTime(this.throttleTime), shareReplay());
}
}
Basically - here I store & get if I need to show app loading animation. I can set this value in multiple components in the same time or with any delays. For example I set isLoading$ to true in one component, and after 0.004sec in another. And everything works fine. Except one case.
Sometimes I need to set isLoading$ to false after it's last true value was set > 20 seconds from now.
How can I reset it to false after it was set to true last time and after 20sec?
I tried so:
constructor() {
this.isLoading$
.pipe(
filter((val) => !!val),
timeout(20000),
)
.subscribe(() => {
this.isLoading$.next(false);
});
}
but looks that it's not working and it takes first true value.
Upvotes: 0
Views: 480
Reputation: 9618
What you probably want to do is:
public get isLoadingAPIVal$(): Observable<boolean> {
return merge(
this.isLoading$,
this.isLoading$.pipe(
debounceTime(20000),
map(() => false),
),
).pipe(
throttleTime(this.throttleTime),
shareReplay(),
);
}
What it does is:
isLoading$
, to get a new signal 20 seconds after isLoading$
last emitted anything:
this.isLoading$.pipe(
debounceTime(20000),
false
values then:
map(() => false),
merge(
this.isLoading$,
this.isLoading$.pipe(
debounceTime(20000),
map(() => false),
),
)
Upvotes: 1