GithubHelp home page GithubHelp logo

nodonisko / ionic-cache Goto Github PK

View Code? Open in Web Editor NEW
261.0 15.0 74.0 1.58 MB

Angular cache service with IndexedDB, SQLite and WebSQL support

License: MIT License

TypeScript 90.52% JavaScript 8.74% Shell 0.74%
cache ionic angular2 websql support-indexeddb offline angular

ionic-cache's Introduction

Ionic cache service

Ionic cache service that can cache almost everything. It caches requests, observables, promises and classic data. It uses Ionic Storage so we support IndexedDB, SQLite (Cordova), WebSQL in this order. It can be used separatelety in Angular 2 application.

Key features:

  • Request caching
  • Delayed observable caching (see docs for more info)
  • Don't invalidate cache if is browser offline
  • Set and invalidate groups of entries
  • Supports IndexedDB, SQLite (Cordova), WebSQL via Ionic Storage

Please report all bugs to bug report or fix it and send pull request :)

Install

Via NPM:

npm install ionic-cache @ionic/storage-angular --save

or Yarn:

yarn add ionic-cache @ionic/storage-angular

You can optionally add Cordova SQLite.

And inject service to your app:

app.module.ts

import { CacheModule } from "ionic-cache";

@NgModule({
  ...
  imports: [
    CacheModule.forRoot()
  ],
})

app.component.ts

import { CacheService } from "ionic-cache";

@Component({
    templateUrl: "build/app.html"
})
class MyApp {
    constructor(cache: CacheService) {
        ...
        cache.setDefaultTTL(60 * 60); //set default cache TTL for 1 hour
        ....
    }
    ...
}

Usage

Config

Starting with version 3.0.2, CacheModule.forRoot() optionally accepts a config object.

The config object currently accepts a keyPrefix, which is the the internal key prefix to use when storing items.

For backwards compatibility this defaults to '', but it's recommended to set this to a different value in order to prevent issues with clearAll().

@NgModule({
  ...
  imports: [
    CacheModule.forRoot({ keyPrefix: 'my-app-cache' })
  ],
})

Observables

Cache request

...
import { CacheService } from "ionic-cache";

@Injectable()
export class SomeProvider {
    constructor(private http: HttpClient, private cache: CacheService) {}

    loadList() {
        let url = "http://ip.jsontest.com";
        let cacheKey = url;
        let request = this.http.get(url);

        return this.cache.loadFromObservable(cacheKey, request);
    }
    ...

Cache whole request response

If you need to cache the whole response, for example if you need to access the Headers, you can pass in an object with the observe key set to 'response', i.e. { observe: 'response' }. Then you can use .pipe(map(res => res.body)) to extract the response body.

...
let request = this.http.get(url, { observe: 'response' });
return this.cache.loadFromObservable(cacheKey, request).pipe(map(res => res.body));
...

Cache with custom Observable operators

loadFromObservable accepts an Observable and returns an Observable, so you are free to use all of the Observable operators. For example error handling (on error, retry request every 6 seconds if fails):

...
let request = this.http.get(url)
.pipe(retryWhen(error => error.timer(6000)));

return this.cache.loadFromObservable(cacheKey, request);
...

Delayed observable caching

loadFromDelayedObservable shows off the full power of observables. When you call this method and it will return the cached data (even if it's expired) and immediately send a request to the server and then return the new data.

...
    let request = this.http.get(url);
    let delayType = 'all'; // this indicates that it should send a new request to the server every time, you can also set it to 'none' which indicates that it should only send a new request when it's expired

    let response = this.cache.loadFromDelayedObservable(cacheKey, request, groupKey, ttl, delayType);

    response.subscribe(data => {
        console.log("Data:" data);
    });

    //result will look like this:
    // Data: "Hello world from cache"
    // Data: "Hello world from server"
...

Promises & Classic data

Cache promises

...
let key = 'some-promise';
let data = await this.cache.getOrSetItem(key, () => somePromiseFunction());
console.log("Saved data: ", data);
...

Cache classic data (arrays, objects, strings, numbers etc.)

Similarly, you can use getOrSetItem or getItem with classic data.

...
let key = 'heavily-calculated-function';

let data = await this.cache.getOrSetItem(key, () => heavilyCalculatedFunction());
console.log('Saved data: ', data);
...

If you need more control in the event that the item is expired or doesn't exist, you can use the getItem method with error handling.

...
let key = 'heavily-calculated-function';

let data = await this.cache.getItem(key)
.catch(() => {
    console.log("Oh no! My promise is expired or doesn't exist!");

    let result = heavilyCalculatedFunction();
    return this.cache.saveItem(key, result);
});

console.log('Saved data: ', data);
...

Removing cached items

You can also remove cached items by using the removeItem method.

...
let key = 'some-promise';

this.cache.removeItem(key);
...

Removing multiple cached items

You can utilize the removeItems method to remove multiple items based on a wildcard pattern.

...
await Promise.all([
    service.saveItem('movies/comedy/1', 'Scott Pilgrim vs. The World'),
    service.saveItem('movies/comedy/2', 'The Princess Bride'),
    service.saveItem('songs/metal/1', 'Who Bit the Moon'),
    service.saveItem('songs/metal/2', 'Deception - Concealing Fate, Pt. 2'),
]);

this.cache.removeItems('songs/metal/*');
...

Cached promise existence

If you need to check whether or not an item has been cached, ignoring whether or not it's expired, you can use the itemExists method.

...
let key = 'some-promise';

let exists = await this.cache.itemExists(key); // returns either a boolean indicating whether it exists or not, or an error message
...

Raw cached item

If you ever need to get a cached item regardless of whether it's expired or not, you can use the getRawItem method.

...
let key = 'some-promise';

let item = await this.cache.getRawItem(key);
...

There's also the getRawItems method, which returns an array of the raw cached items.

...
let rawItems = await this.cache.getRawItems();
let firstItem = rawItems[0]; //Has the properties: key, value, expires, type, groupKey
...

Other

Cache entries grouping

At times you may need to clear certain groups of cached items. For example, if you have an infinite scroll list with a lot of items and the user triggers a pull to refresh, you may want to delete all of the cached list items. To do this, you can supply a group key as the 3rd parameter of loadFromObservable.

...
loadList(pageNumber) {
    let url = "http://google.com/?page=" + pageNumber;
    let cacheKey = url;
    let groupKey = "googleSearchPages"

    let request = this.http.get(url);
    return this.cache.loadFromObservable(cacheKey, request, groupKey);
}
...

Then when pull to refresh is triggered, you can use the clearGroup method and pass in your group key.

...
pullToRefresh() {
    this.cache.clearGroup("googleSearchPages");
}
...

Set custom TTL for single request

If you want a custom TTL for a single request, you can pass it as the fourth parameter.

let ttl = 60 * 60 * 24 * 7; // TTL in seconds for one week
let request = this.http.get(url);

return this.cache.loadFromObservable(cacheKey, request, groupKey, ttl);

Set default TTL

this.cache.setDefaultTTL(60 * 60); //set the default cache TTL for 1 hour

Delete expired entries

It's automatically done on every startup, but you can do it manually.

this.cache.clearExpired();

Delete all entries

!Important!

Make sure that you have a keyPrefix set in the CacheModule config, otherwise this will clear everything in Ionic Storage.

this.cache.clearAll();

Disable cache

You can disable cache without any issues, it will pass all of the original Observables through and all Promises will be rejected.

this.cache.enableCache(false);

Disable offline invalidation

You can also disable invalidating cached items when the device is offline.

this.cache.setOfflineInvalidate(false);

Contributors โœจ

Maintainers:

Thanks goes to these wonderful people (emoji key):


Daniel Suchรฝ

๐Ÿค” ๐Ÿ“– ๐Ÿ’ป ๐Ÿ‘€

Will Poulson

๐Ÿ“– ๐Ÿ’ป ๐Ÿ‘€

Ibby Hadeed

๐Ÿ’ป

Bowser

๐Ÿ’ป

Vojtฤ›ch Tranta

๐Ÿ’ป

Bruno Frare

๐Ÿ’ป

This project follows the all-contributors specification. Contributions of any kind welcome!

ionic-cache's People

Contributors

adityasharma7 avatar aemr3 avatar cocowalla avatar danielsogl avatar darthdie avatar dependabot[bot] avatar djereg avatar eesdil avatar elodiec avatar fjmoron-clece avatar frankrue avatar gazaret avatar ihadeed avatar imatefx avatar jarmokukkola avatar joegarb avatar kygoh avatar mcroker avatar nodonisko avatar pestig avatar ramonornela avatar ricmello avatar thiagocleonel avatar vojtatranta avatar willpoulson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ionic-cache's Issues

Lack of documentation

This is really nice API for caching.But the problem is a lack of documentation.Please at least put all the methods which we can use. Such very important method is removeItem().We cannot see anything about it inside the readme.Thanks for the awesome API.

no such key

hi!
I use the function which is the loadFromObservable in ionic3.it cause a error when run.
error:
Uncaught (in promise): No such key: http://ip.jsontest.com

my function(it's your demo,why?)
loadList() {
let url = "http://ip.jsontest.com";
let cacheKey = url;
let request = this.http.get(url).map(res => res.json());

return this.cache.loadFromObservable(cacheKey, request);

}

CacheService object undefined

(step1) install the ionic-cache
ionic plugin add cordova-sqlite-storage
npm install ionic-cache --save
(step2) usage
...
import {CacheService} from "ionic-cache/ionic-cache";
export class MyApp {
private rootPage: any;
pages: Array<{title: string, component: Type}>
constructor(private platform: Platform, private menu:MenuController, private app:App,private cache: CacheService ) {
this.cache = cache;
console.log(this.cache); // Here this.cache is "undefined" from Chrome console
....
}

ionicBootstrap(MyApp, [
CacheService
]);

-------env info--------------------
Cordova CLI: 6.3.0
Gulp version: CLI version 3.9.1
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.11
Ionic CLI Version: 2.0.0-beta.37
Ionic App Lib Version: 2.0.0-beta.20
ios-deploy version: 1.8.6
ios-sim version: 5.0.7
OS: Mac OS X Yosemite
Node Version: v4.5.0
Xcode version: Xcode 7.2.1 Build version 7C1002

Return expired items

On some cases, I'd rather get an expired item (and attempt to update it on the background) than to do an actual request. Is it possible to implement something like that? I wrote a small service for this, but on this library I guess it would mean a core change (flag on items for wether they should be purged on cleanups or not).

.isOnline() inconsistent result

I tried connecting my phone via WiFi and mobile data but most of the time .isOnline() returns false.
Only once it returned true and I can't tell why.
Any idea why this happens?

Authentication could make it fail

Hello!

I am getting this error, error = TypeError: response.json is not a function at MapSubscriber.project (http://localhost:8100/build/main.js:41776:33) at MapSubscriber._next

I am using this library, https://github.com/auth0/angular2-jwt for handling JWTs

This is my code

let cacheKey = cms.offers;
let request = this.authHttp.get(cms.offers);
return this.cache.loadFromObservable(cacheKey, request).map(
    (response: Response) => {
        const data = response.json();
        return data;
    }
).catch(
    (error: Response) => {
        if (error.status == 403 || error.status == 0) {
            console.log(error + " error token 403");
            this.authService.logout();
            return [];
        } else {
            return Observable.throw('Error getting offers list. Code: ' + error.status);
        }
    }
);

When I am debugging I am getting an empty response,

What could be happening here?

Thank you

Not working in IOS simulator or IOS device but working for android and ionic serve

Hi,

I have used your plugin in my project and in first phase I created android build and have released and it is working great.

Now, when I am trying to create an IOS build it is not working. I tried IONIC serve and it is coming fine and working good but in IOS simulator and IOS device returning no response and loader never gets terminated.

	public getPosts(query, pulltorefresh = false) {
		query = this.transformRequest(query);
		let url = this.config.webApiUrl+ `/webapi?${query}&_embed`;
        let cacheKey = url;
    	let groupKey = cacheKey;
	        let request = this.http.get(url).map(res => res.json());
	        return this.cache.loadFromDelayedObservable(cacheKey, request, groupKey, this.config.cacheTime, delayType);

	}

Thanks Sanny

Cache doesn't seem to work

Hello, I've implemented the cache service like in the documentation in this repo.
But when I try to reopen the page in my app several times, it's continuesly making a new http request instead of returning the cached data.
When I try to inspect my app with Safari I see that it's building a cache in the database under "Storage", but when trying to view the data Safari is not responding anymore and I have to restart Safari again.
Am I doing something wrong?

// Constructor
this.cacheService.setDefaultTTL(60 * 60);

// GET-request
let request = this.http.get(this.config.getApi().getUrl() + endpoint, this.getHeaders(this.token));
        return this.cacheService.loadFromObservable(endpoint, request)
        .map((response: Response) => {
            return this.getResponse(response);
        })
        .catch(response => {
            return Rx.Observable.throw(response.json().message || 'A server communication error has been throwed.');
        });

The same request for several times in a few seconds. The time to load the response is getting worse instead of better when reloading the page.
schermafbeelding 2017-01-22 om 23 03 15

Chaining...

Hi,

How is it possible ton chain several promises caches. It's not working if I do like this:

let key1 = 'some-promise1';
this.cache.getItem(key1).catch(() => {
    return somePromiseFunction().then(result => {
        return this.cache.saveItem(key1, result);
    });
}).then((data) => {
    console.log("Saved data1: ", data);
});
let key2 = 'some-promise2';
this.cache.getItem(key2).catch(() => {
    return someOtherPromiseFunction().then(result => {
        return this.cache.saveItem(key2, result);
    });
}).then((data) => {
    console.log("Saved data2: ", data);
});
...

What will be the best way to do it ?

Vincent

getOrSetItem : missing params...

Hi,

The line

     await this.saveItem(key, val);

in the following function

async getOrSetItem<T>(key: string, factory: CacheValueFactory<T>, groupKey: string = 'none', ttl: number = this.ttl): Promise<T> {
   let val: T;

   try {
     val = await this.getItem(key);
   } catch (error) {
     val = await factory();
     await this.saveItem(key, val);
   }

   return val;
 }

should be

 this.saveItem(key, val, groupKey, ttl);

Unable to get cached data

The data is saved correctly, but when i try to get it it returns
No such key: items_by_name
But the key exists in webSQL database cache

Endless TTL

I know it looks kinda counterintuitive, but for some purposes (ie. AngularFire authentication) it would be nice to have an immortal cache item. AngularFire has its own TTL and it's gets really messy when those two intervals aren't in sync. TTL = -1 would do the trick.

Cache loading inconsistent in browser

I know this is probably more of a "nice to have" than a must. But I've noticed when using the browser to test the loading times from cache can be up to 10-20 seconds sometimes without making an external call. Other times it is fast as a device. Where on a device it is always consistently fast.

Cordova CLI: 6.5.0
Ionic Framework Version: 2.0.1
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.0.0
ios-deploy version: 1.9.1
ios-sim version: 5.0.13
OS: macOS Sierra
Node Version: v6.9.5
Xcode version: Xcode 8.2.1 Build version 8C1002

And browser I am testing in Chrome(Version 56.0.2924.87 (64-bit)) with device emulation in dev tools emulating both Galaxy S5 or iPhone 6 usually.

Improve work non-observables

This is not so smart, you must call getItem twice...

...
let arrayToCache = ["Hello", "World"];
let cacheKey = "my-array";

return new Promise((resolve, reject) => {
    this.cache.getItem().then(item => {
        resolve(item);
    }).catch(() => {
        this.cache.saveItem(cacheKey, arrayToCache).then(() => {
            this.cache.getItem().then(item => {
                resolve(item);
            });
        });
    });
});
...

clearAll() removes everything in ionic Storage

I'm using ionic storage to store long-term preferences handled by another service and just discovered that clearAll() removes everything from storage - not just those cached entries managed by ionic-cache.

At application start up I want to be able to completely clear the ionic-cache entries without destroying my long-term preferences.

I understand cache groups can be used to handle this case, however I am actually using these as a means to manage related data primarily derived from http get calls.

My workaround is to prefix all my cache keys with 'ionic-cache:' and then iterate over the keys ( this.storage.keys() ) at start up, calling this.storage.remove() to remove the entries one by one from ionic Storage

It would be nice if some kind of root key/prefix could be employed as a configuration option so that I don't have to jump through hoops - basically a call to clearAll() will only destroy cache entries that contain the root key/prefix.

Apart from my little issue, I have to say this is a superb service that everyone should be using in their ionic apps - It circumvents the need to set up and manage caching using those pesky SQLite tables etc.

for Ionic 1 ?

Do we have a version available for Ionic 1 ?
Thanks

Observable error handling

Hey guys, I can't catch http errors when using loadFromObservable.

Here is my provider method:

test() {
  let request = this.http.get(this.API_URL)
    .timeout(20000)
    .map(resp => resp.json());

  return this.cache.loadFromObservable(this.API_URL, request);
}

In my component I call:

this.myProvider.test().subscribe(
    data => console.log('cool'),
    error=> console.log('not cool')
  );

When any http error is thrown, none of them is fired.

Cannot find module "localforage"

Hi,

I tried installing this plugin but my app showing error and says

Cannot find module "localforage"

Here is my package.json


{
  "name": "MyApp",
  "author": "Sanny Srivastava",
  "homepage": "***.com",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "2.2.1",
    "@angular/compiler": "2.2.1",
    "@angular/compiler-cli": "2.2.1",
    "@angular/core": "2.2.1",
    "@angular/forms": "2.2.1",
    "@angular/http": "2.2.1",
    "@angular/platform-browser": "2.2.1",
    "@angular/platform-browser-dynamic": "2.2.1",
    "@angular/platform-server": "2.2.1",
    "@ionic-native/core": "^3.6.1",
    "@ionic-native/device": "^3.13.0",
    "@ionic-native/facebook": "^3.14.0",
    "@ionic-native/geolocation": "^3.13.1",
    "@ionic-native/push": "^3.13.0",
    "@ionic/cloud-angular": "^0.12.0",
    "@ionic/storage": "^2.0.1",
    "angular2-google-maps": "^0.16.0",
    "chart.js": "^2.5.0",
    "ionic-angular": "2.1.0",
    "ionic-cache": "^2.0.5",
    "ionic-native": "2.4.1",
    "ionicons": "3.0.0",
    "moment": "2.15.1",
    "ng2-translate": "^3.1.3",
    "rxjs": "5.0.0-beta.12",
    "sw-toolbox": "3.4.0",
    "zone.js": "0.6.26"
  },
  "devDependencies": {
    "@ionic/app-scripts": "1.1.3",
    "typescript": "2.0.9"
  },
  "cordovaPlugins": [
    "cordova-plugin-whitelist",
    "cordova-plugin-statusbar",
    "cordova-plugin-console",
    "cordova-plugin-device",
    "cordova-plugin-splashscreen",
    "ionic-plugin-keyboard",
    "cordova-plugin-crosswalk-webview",
    "cordova-plugin-inappbrowser",
    "cordova-plugin-x-socialsharing",
    "phonegap-plugin-barcodescanner",
    {
      "variables": {
        "APP_ID": "*************",
        "APP_NAME": "MyApp"
      },
      "locator": "[email protected]",
      "id": "cordova-plugin-facebook4"
    },
    "cordova-plugin-email"
  ],
  "cordovaPlatforms": [],
  "description": "MyApp"
}

Please let me know about the issue.

Thanks Sanny

successful caching

how do I know caching has been done successfully? I have to fetch some stuff from a web service but things don't seem to work offline. I need help.

Errors are not passed through observable chain

So I have a service that wraps an http endpoint, and passes the observable back to a page. If an error happens the cache is preventing the error from getting passed to the page, and is only hitting the error handler in the service and not the page. It isn't even hitting the completion handler from the subscribe either, the error in the service seems to be stopping it.

If I return the request directly the errors happen as I would expect, service and page.
If I cache the request, the service error is called but not the page error, even if there is no data already in the cache. I could see it not throwing the error if there was data in the cache.

I am not the most familiar with RxJs Observables so maybe this is an error on my part, but something still seems fishy with the cache not throwing the error.

Service:

loadAllDeals(): Observable<Deal[]> {
    let request = this.http.get(AppConfig.API_URL+'/users/'+this.user.auth_token()+'/deals')
      .map(res => <Deal[]>res.json())
      .catch(this.handleError);

    // return request;
    let response = this.cache.loadFromDelayedObservable(DealsService.cacheKey, request);
    return response;
  }

handleError(error) {
    console.log("DealsService handleError");
    return Observable.throw(error);
  }

Page:

loadDeals(locid?) {
    this.loading.present();
    this.DealsService.loadAllDeals()
      .catch(e => {return Observable.throw(e);})
      .subscribe(data => {
        this.deals = data;
      },
      (err) => {this.handleError(err);},
      () => {console.log("complete");}
    );
  }

handleError(error) {
    this.loading.dismiss();
    console.log("DealsPage handleError:");
    console.error(error);
    alert.present();
  }

Cannot include in karma-jasmine unit test project

Can you please advise on how to integrate the project into karma-jasmine unit test?
The project does not contain bundles/*.umd.js file.

Getting the:
WARN [web-server]: 404: /base/ionic-cache/ionic-cache

Thanks

Using ionic-cache with angular 4 HttpInterceptor

Hello,
I want to cache the data from any GET method fired from my app. To do so, I am using httpInterceptor in order to intercept the http requests:

import {Injectable} from "@angular/core";
import {
  HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest,
  HttpResponse
} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
import {CacheService} from "ionic-cache";

@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  constructor(public cache: CacheService) {}
  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const cacheKey = req.url;
    const request = next.handle(req);
    if (req.method === "GET") {
      return this.cache.loadFromObservable(cacheKey, request);
    }
    return next.handle(req);
  }
}

So I tried the code above but it doesn't seem to work, the client does not receive any data, plus no error is fired and nothing appears in the console.
Does anyone have a working use case scenario ?

I am on Ionic 3.19.0 btw

ngFor not working after adding cache

Hi everyone,
I've just added this module to my application and it works just fine for all the pages, except from the following one:

<ion-header>

  <ion-navbar>
    <ion-title>{{navParams.get('name')}}</ion-title>
  </ion-navbar>

</ion-header>


<ion-content padding>
  <ion-segment [(ngModel)]="view">
    <ion-segment-button value="info">
      Info
    </ion-segment-button>
    <ion-segment-button value="recensioni">
      Recensioni
    </ion-segment-button>
  </ion-segment>

  <div [ngSwitch]="view">
    <div id="info">
      <div *ngSwitchCase="'info'">
        <div class="flexBox">
          <div *ngIf="details != undefined" [style.background]="(details.open_now) ? 'green' : 'red'"></div>
          <span *ngIf="details != undefined && details.open_now">Aperto</span>
          <span *ngIf="details != undefined && !details.open_now">Chiuso</span>
          <ion-icon name="call" (click)="call()"></ion-icon>
          <ion-icon name="navigate" (click)="navigateTo()"></ion-icon>
        </div>
      </div>
      <div #map2 [style.height]="(view == 'info') ? '35vh' : '0px'"></div>
      <div *ngSwitchCase="'info'" id="slides">
        <ion-slides *ngIf="details != undefined">
          <ion-slide *ngFor="let img of details.photos" (click)="openImg($event)">
            <img [src]="'https://maps.googleapis.com/maps/api/place/photo?key=AIzaSyD_9bj_Ao6nklX7PWrM_1E-iDH4EPVWV6A&maxwidth=1600&photoreference=' + img.photo_reference" />
          </ion-slide>
        </ion-slides>
      </div>
    </div>

    <div id="rec">
      <div *ngSwitchCase="'recensioni'">
        <ion-list-header>
          <div id="avg">
            <div>
              <span item-start text-wrap>Voto Google: </span>
              <span item-end text-wrap class="end" *ngIf="navParams.get('rating') != undefined">{{navParams.get('rating')}}/5</span>
              <span item-end text-wrap class="end" *ngIf="navParams.get('rating') == undefined">Nessuna valutazione!</span>
            </div>
            <div>
              <span item-start text-wrap class="start">Voto Tripadvisor: </span>
              <ion-spinner item-end text-wrap class="end" *ngIf="!loaded" name="dots"></ion-spinner>
              <span item-end text-wrap class="end" *ngIf="loaded && rating != undefined">{{rating}}/5</span>
              <span item-end text-wrap class="end" *ngIf="loaded && rating == undefined">Nessuna valutazione!</span>
            </div>
          </div>
        </ion-list-header>
        <ion-list>
          <ion-item *ngFor="let recensione of reviews">
            <div class="center">
              <ion-avatar>
                <img [src]="recensione.profile_photo_url">
              </ion-avatar>
            </div>
            <p class="name">{{recensione.author_name}}</p>
            <div class="rating">
              <div class="star-ratings-sprite">
                <span [style.width]="(100*recensione.rating/5) + '%'" class="star-ratings-sprite-rating"></span>
              </div>
            </div>
            <div *ngIf="recensione.title != undefined" class="title">
              <span text-wrap>{{recensione.title}}</span>
            </div>
            <span class="review" text-wrap>{{recensione.text}}</span>
            <div class="date">
              <p>{{recensione.relative_time_description}}</p>
            </div>
          </ion-item>
        </ion-list>
        <ion-spinner *ngIf="!loaded"></ion-spinner>
        <ion-infinite-scroll (ionInfinite)="scrapeNext($event)" threshold="1000px">
          <ion-infinite-scroll-content></ion-infinite-scroll-content>
        </ion-infinite-scroll>
      </div>
    </div>
  </div>
</ion-content>

In this page I show infos and reviews about a specific restaurant (the reviews are displayed inside the ion-list). To retrieve the reviews I used the following code in the .ts file:

this.scraper.getTaReviews(this.navParams.get('name'))
  .subscribe(data => {
    console.log(data)
    if (data != "no data") {
      this.placeId = data.placeId;
      this.risId = data.risId;
      this.hasNext = data.hasNext;
      this.rating = data.avgRating;
      this.reviews = this.reviews.concat(data.reviews);
      console.log(this.reviews);
    }
    this.loaded = true;
  })

Obviously I initiated the reviews variable to be an empty array in the constructor.

This is the function that is called to make the http call:

 getTaReviews(ris: string) {
    let request = this.http.get(this.hostname + ':8090/tarev?ris=' + ris + '&citta=' + this.share.getProvincia()).map(res => res.json()).retry();
    return this.cache.loadFromObservable(ris + "-" + this.share.getProvincia(), request);
    // return this.http.get(this.hostname + ':8090/tarev?ris=' + ris + '&citta=' + this.share.getProvincia()).map(res => res.json()).retry();
  }

The uncommented part is the new one, and the commented part is the old working one. My problem is that the first time I open the page and get the data, everything works just fine and the reviews in the ion-list are displayed correctly. When I use cached data, however, the ion-items inside the list are not populated, even though the reviews array contains the correct data (I checked it in the console log). As I said before, it works just fine if I don't use ionic-cache, but I can't really explain why this behaviour affects only this page. Moreover, all the other cached data (except from the reviews) is displayed correctly, it looks like it is a problem just with the ngFor statement.

cache-storage

Question: use saveItem with loadFromObservable?

Perhaps I have overlooked something in de docs, but I am wondering if I need to use saveItem first before I call loadFromObservable? My plan is to integrate ionic-cache into my generic Api provider that handles all HTTP traffic. I have something similar to the loadList example:

request(method: string, endpoint: string, body: any, options?: RequestOptions): Observable<any> {
    // Some other code
    ...
    const apiCall = this.http.get(url, options);
    const key = `prefix:${endpoint}`;
    return this.cache.loadFromObservable(key, apiCall.map(res => res.json()));
  }

However, using it like this results in a Runtime Error saying "No such key". Therefore I thought I might be calling saveItem first? Can you perhaps point me in the right direction?

Many thanks!

Proposal: Strongly Typed Cache Items

In PR #51 I introduced a method that allows users, with a single call, to get an existing cache item or generate and store a new one.

I also made that method strongly typed, such that it returns T and the value factory must produces a T.

I'd like to propose that all get/set methods use typed values and parameters instead of any, so we can make better use of Typescript's type system.

clearGroup not clear

After the first call clearGroup I noticed that the items are not remotely. So the request is only during the second attempt.

Prepopulate cache

Is there any possibility to "prepopulate" the cache in case the user wants to use the app offline after installing?

Possible to save 17MB?

Hi all.
I am using ionic 3 and I want to save 17MB json data in the local.
First, I thought using local storage but the limit in mobile is 5MB :(
So I ended up here.

I am wondering if this plugin fits with my demand. Is there a page that I can check limit of storage ?

Thank you.

TypeError: observable.share is not a function

I am getting a

TypeError: observable.share is not a function
at CacheService.loadFromObservable (cache.service.js:240)

and the line points to
observable = observable.share();

is there something I am missing? that I need to import?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.