Below are the base observables that mimic my code:
class DataService {
#data = this.http.get<Data[]>('https://example.com/getData').pipe(
timeout(15000),
catchError(err => of([]))
)
#adaptedData = this.#data.pipe(
map(data => data.map(obj => new AdaptedObj(obj)))
)
#pollAdapted = timer(0, 60000).pipe(
switchMap(() => this.#adaptedData),
shareReplay(1)
)
get get() { return this.#adaptedData }
get poll() { return this.#pollAdapted }
}
Then elsewhere in my code I have an additional layer of observables that further manipulate the data for use in a particular set of components. Examples:
class DataAnalyzerService {
constructor(private dataService: DataService){}
#analyzedDataStore = new BehaviorSubject<AnalyzedData[]>([])
get analyzedData() { return this.#analyzedDataStore.value }
#analyzedData = this.dataService.poll.pipe(
filter(objs => objs.length > 0),
map(objs => objs.map(obj => new AnalyzedObj(obj))),
tap(analyzedData => this.#analyzedDataStore.next(analyzedData))
)
#metricCalculator = () => {
const data = this.analyzedData
// Do calculations and filtration
return dashboardMetricsArr
}
#dashboardStats = this.#analyzedData.pipe(
switchMap(() => of(this.#metricCalculator))
)
get dashboardStats() { return this.#dashboardStats }
}
Then in my component I am using the dashboard metrics with an async pipe like this:
<ng-container *ngIf="(dashboardStats | async) as stats">
// Use the Data
<ng-container>
The reason I have the observables broken up like this is because there are different components that will need the data at different layers of analysis, additionally, some components will only need the data once and others will need it constantly updated at the 1 minute interval.
Currently, the application works fine, but when I logout or exit the components that use the data, I notice the http requests are ongoing each minute because the DataService
poll
observable is never unsubscribed. Right now, I only have a single subscription initialized using the async pipe in the template, so I know I am closing that specific subscription when I navigate away from that component or log out all-together. Additionally, I have verified that both the #analyzedData
and #dashboardStats
observables cease execution after navigating away. Only the poll
observable continues.
Any ideas on how to get the polling to stop until I am back in a component that needs it?
shareReplay
has therefCount
config option as described in the manual:You use
shareReplay(1)
, which uses the default valuerefCount: false
, hence it will not unsubscribe. Turn on reference counting for automatic unsubscription:shareReplay({bufferSize: 1, refCount: true})