stijn26 stijn26 - 1 year ago 112
HTTP Question

Cache data but check in the background for new data

I want to cache my data, but at the same time I need my data to be up-to-date. I found this: Angular2 easiest way to cache HTTP responses but this will not check for new data.

I have this now in my service:

public publishedSessions: Session[] = null;

getPublishedSessions(): Observable<any> {
let headers = new Headers();
headers.append('authorization', this.userService.getToken());

if (this.publishedSessions) {
this.http.get(this.apiUrl + 'api/sessions/published', {
headers: headers
.map(res => res.json().sessions)
.subscribe(sessions => this.publishedSessions = sessions);

return Observable.of(this.publishedSessions);
} else {
return this.http.get(this.apiUrl + 'api/sessions/published', {
headers: headers
.do(res => this.publishedSessions = res.json().sessions)
.map(res => res.json().sessions)
.catch((error) => Observable.of(error));

And some standard code in my component:

handlePublishedSessions(): void {
this.subscriptionArr.push(this.sessionService.getPublishedSessions().subscribe(sessions => {
this.session = sessions

This causes the effect that when I first navigate (visit 1) to the page, a call (call 1) will be made (wanted). Then if I navigate away and return back to the page (visit 2), the data from call 1 will be returned (not wanted), in the meantime, call 2 is in the works. So if I then navigate away again and navigate back (visit 3), the data from call 2 is being returned.

I want that the call 1 data is displayed on visit 2 for the first few milliseconds (untill call 2 is done). When call 2 is done I want the data to be replaced (without user interaction).

Answer Source

I would use a BehaviorSubject to cache data.

Take a look at this plunker to get an idea:

import {Component, NgModule, Injectable} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {HttpModule, Http} from '@angular/http';

import {BehaviorSubject} from 'rxjs/Rx';

export class AnyService {

  public data = new BehaviorSubject<string>();

  constructor(private _http: Http) { }

  public getData(): string {
        resp =>

  selector: 'my-app',
  template: `
      <h2 (click)="getData()">Hello {{name}} -- CLICK ME !! --</h2>
export class App {

  firstSubscribeCallback = false;

  constructor(private _srvc: AnyService) { = 'Angular2'
      newData => {

        if (!this.firstSubscribeCallback) { // JUST FOR DEMO ..

          console.log('got cached data @ startup..');
          this.firstSubscribeCallback = true;

        else console.log('got new data:');


    this.getData(); // get FRESH data ..

  getData() {
    console.log('getting cached data:');

  imports: [ BrowserModule, HttpModule ],
  declarations: [ App ],
  providers: [ AnyService ],
  bootstrap: [ App ]
export class AppModule {}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download