I have a simple cache service which may suit your needs @polska03
I use it to cache frequent GET requests to a local key/value pair. If the cache is expired or doesn’t yet exist for that key, then it grabs and stores the result (with the option of passing in a TTL for the cache in seconds, or none for default TTL.)
I also have an event I subscribe to in order to invalidate the whole cache when I make any dynamic updates that I can publish to when I need to clear out the cache completely.
Hope this helps, you should be able to tweak to your needs if you find it useful. It currently only does GET requests but so far that’s all I’ve needed it for.
// app/services/cache/simple_cache.ts
import {Storage, SqlStorage, Events} from 'ionic-angular';
import {Http} from 'angular2/http';
import {Injectable} from 'angular2/core';
import {API_URL} from '../../config'; // this is my API URL, change it to yours
const CACHE_TTL = 60 * 60; // 1 hour
@Injectable()
export class SimpleCacheService {
private storage: Storage;
constructor(private events: Events, private http: Http) {
events.subscribe('cache:invalidate', () => {
this.cacheInvalidate();
});
this.storage = new Storage(SqlStorage);
}
/**
* Invalidate Cache
* @returns {Promise<any>}
*/
public cacheInvalidate(): Promise<any> {
return this.storage.clear();
}
/**
* Get Cached Item
* @param {string} name - Cache key
* @param {string} location - API endpoint of cached item
* @param {number=} ttl - TTL in seconds (-1 to invalidate immediately)
* @returns {Promise<{}>}
*/
public getItem(name: string, location: string, ttl?: number): Promise<{}> {
// if ttl is < 0, delete cached item and retrieve a fresh one
if (ttl < 0) {
this.storage.remove(name);
}
return new Promise((resolve, reject) => {
this.storage.get(name).then(cachedResult => {
if (typeof cachedResult !== 'undefined') {
// something's in the cache
let data = JSON.parse(cachedResult);
if (this.itemExpired(data)) {
// cache IS expired
this.load(location)
.then(res => this.setItem(name, res, ttl).then(() => resolve(data.data)))
.catch(err => reject(err));
} else {
// cache is NOT expired
resolve(data.data);
}
} else {
// not in the cache (key doesn't exist)
this.load(name)
.then(res => this.setItem(name, res, ttl).then(() => resolve(res)))
.catch(err => reject(err));
}
}).catch(err => reject(err));
});
}
/**
* Set Cached Item
* @param {string} name - Key name of item to store
* @param {any} data - Value of data to store
* @param {ttl=} ttl - TTL in seconds
*/
public setItem(name: string, data: any, ttl?: number): Promise<{}> {
let expiration = (typeof ttl !== 'undefined' && ttl) ? this.currentTimestamp() + ttl : this.currentTimestamp() + CACHE_TTL;
let value = JSON.stringify({ data: data, expires: expiration});
return this.storage.set(name, value);
}
/**
* Delete Cached Item
* @param {string} name - Key name of item to delete
* @returns {Promise<any>}
*/
public deleteItem(name: string): Promise<any> {
return this.storage.remove(name);
}
/**
* Check Item for Expired Cache
* @param {data: any, expires: number} item - Cache item
* @returns {boolean}
*/
private itemExpired(item: {data: any, expires: number}): boolean {
return (typeof item !== 'undefined' && typeof item.expires !== 'undefined') ?
this.currentTimestamp() > item.expires : true;
}
/**
* Get Current Timestamp
* @returns {number}
*/
private currentTimestamp(): number {
return Math.floor(new Date().getTime() / 1000);
}
/**
* Load from API Endpoint
* @param {string} path - Endpoint to grab
*/
private load(path: string): Promise<{}> {
return this.http.get(API_URL + path).map(res => res.json().data).toPromise();
}
}
which you would call using something like this:
// app/components/some_component.ts
import {IONIC_DIRECTIVES} from 'ionic-angular';
import {Component} from 'angular2/core';
import {SimpleCacheService} from '../../services/cache/simple_cache';
@Component({
...
})
export class SomeCmpt {
private filters: any[];
private morefilters: any[];
constructor(private simpleCache: SimpleCacheService) {
// where 'filters' would be the key in cache
// and 'filters/list' would be the endpoint of your API
simpleCache.getItem('filters', 'filters/list')
.then(res => this.filters = res)
.catch(err => console.log('oops', err));
// you can also pass in an expiration time in seconds
simpleCache.getItem('morefilters', 'filters/list/more', 60 * 60 * 24)
.then(res => this.morefilters = res)
.catch(err => console.log('oops', err));
}
}