Caching Data From HttpClient in Angular 4

Viewed 11213

i have a problem in making my caching more simpler. I think there is a better way to do this. My problem is that i have to do this "caching" codes in every get() function which is results in longer codes. Anyone help on how to do this the best way? Thanks. Here's my codes below. What i did in my codes is i do the get() function in my news.service.ts to get data from the http and i subscribe it in my news-list.

news.service.ts

getAllNews() {

    if(this.newslist != null) {
      return Observable.of(this.newslist);
    } 

    else {

      return this.httpClient
        .get('http://sample.com/news')
        .map((response => response))
        .do(newslist => this.newslist = newslist)
        .catch(e => {
            if (e.status === 401) {
                return Observable.throw('Unauthorized');           
            }

        });
    }
  }

news-list.service.ts

 this.subscription = this.newsService.getAllNews()
      .subscribe(
        (data:any) => {
          console.log(data);
          this.newslists = data.data.data;
        },
        error => {
          this.authService.logout()
          this.router.navigate(['signin']);
        });
  }
2 Answers

I'm not too sure what the difference between news.service.ts and news-list.service.ts is but the main concept is that you need to separate concerns. The most basic separation you can do is by distiguishing "data providers" from "data consumers"

Data Providers

This could be anything that fetches and manages data. Whether in-memory cached data, a service call, etc. In your example, it seems to me that news.service.ts it's a Web API client/proxy for everything related to news.

If this is a small file you could move all news-related cache management to this file or...create another component that manages cache and wraps news.service.ts. That component would serve data from its cache, if the cache doesn't exist or has expired, then it calls on news.service.ts methods. This way news.service.ts's only responsbility is to make ajax requests to the API.

Here's an example without promises, observables or error handling just to give you an idea...

class NewsProvider{

    constructor(){
        this.newsCache = [];
    }

    getNewsItemById(id){
        const item = this.newsCache.filter((i) => {i.id === id});

        if(item.length === 1) return item[0];

        this.newsCache = newsService.getAllNews();

        item = this.newsCache.filter((i) => {i.id === id});

        if(item.length === 1) return item[0];
        else return null;
    }
}

Data Consumers

These would be any component that needs data, a news ticker in the home page, a badge notification somewhere in the navigation menu....there could be any components (or views) needing news-related data. For that reason, these components/views shouldn't need to know anything about where that data is coming from.

These components will use "data providers" as there main source of data

Summary

Cache only needs to be (and can be) managed in one single place as well as network-related operations

Related