When interacting with observables, we typically set up a subscription on the consumer side and react to values coming through the pipe. We can easily add caching to the observables by adding publishReplay(1) and refCount.If you lean into observables as a means of sharing data, you can adopt the following approach:import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http';import { Observable, ReplaySubject } from 'rxjs';import { SomeModel } from 'path/to/it';@Injectable({providedIn: 'root' }) export class CachedService {private dataSubject = new ReplaySubject(1);data$: Observable = this.dataSubject.asObservable();constructor(private http: HttpClient) { }fetch() {this.http.get(...).subscribe(res => this.dataSubject.next(res));} } This will make an HTTP call when the fetch method is called, and any subscribers to service.data$ will get the response from the ReplaySubject. As it replays earlier values, any subscribers who join after the HTTP call resolves will still get the previous response.If you want to trigger an update, you can just call service.fetch() to kick off a new HTTP call and all subscribers will be updated once the new response arrives.Your components would then look something like:@Component({ ... }) export class SomeComponent implements OnDestroy, OnInit {private subscription?: Subscription;constructor(private service: CachedService) { }ngOnInit() {this.service.fetch();this.subscription = this.service.data$.subscribe(...);}ngOnDestroy() {if (this.subscription) {this.subscription.unsubscribe();}} }