The best way to remove key from Storage


#1

Hi i Have set many key in the ionic storage for avoid get call any click on that page.

Now if I would like that anytime i open the app this variable were deleted!

Any solution for me?

This is my code

  constructor(public navCtrl: NavController, private http: Http, public loadingCtrl: LoadingController, public alertCtrl: AlertController, private app: App, public storage: Storage) {

    this.storage.get('events_home').then((data) => {
      if (data != null) {
        this.get_storage_data();
      }
      else {
        this.loading.present();
        this.get_events(this.refresher);
      }
    })

  }

  get_storage_data() {
    this.loading.dismiss();
    this.storage.get('events_home').then((val) => {
      this.todayitems = val.today;
      this.afteritems = val.after;
      this.sponsoreditems = val.sponsored;
      console.log('Today Events ', this.afteritems);
    })
  }

get_events(refresher) {
    this.http.get("http://www.cinemairis.it/wp-json/wp/v2/events").subscribe(data => {
      this.todayitems = JSON.parse(data['_body']).today;
      this.afteritems = JSON.parse(data['_body']).after;
      this.sponsoreditems = JSON.parse(data['_body']).sponsored;
      this.items = JSON.parse(data['_body'])
      console.log("CIAO CIAO BAMBINA" + this.items);
      this.storage.set('events_home', this.items);


      this.total = this.todayitems.length;

      if (refresher != undefined) {
        refresher.complete();
      }

      this.loading.dismiss();
    },

      error => {
        console.log(error);


        setTimeout(() => {
          let alert = this.alertCtrl.create({
            title: "Nessuna Connessione",
            subTitle: "Si prega di riprovare",
            buttons: ["OK"]
          });
          alert.present();
        }, 1000);
        console.log(error);// Error getting the data

      });


  }

#2

Among the many things I don’t understand:

  • why you’re bothering to store something that you don’t want to persist across app restarts
  • why you’re loading events_home from storage once, throwing it away, and then reloading it again immediately
  • why you only dismiss the loader on success
  • why you are calling JSON.parse(data['_body']) at all (let alone a zillion times), when calling the public API json() function once would do
  • why you are wrapping your alert presentation in setTimeout

All that said, ionic-storage has a remove method.


#3

Thank you for your time.

first and second question: Because in menu i have many section and when i click on specific page this page recall a json function. with this method when i open the app I save the data in the storage.

third question: in case of success i remove the loader and i set the data in the storage.

fourth question: you’re right :slight_smile:

five question: in case of error i wait a second before popup appears on the screen

Essentially I expose my problem. When i open the app I would like that I have a new dates from json and i storage that with the possibility of re-downloading through the refresh function.
Now when I remain in the app i use the data from storage when I restart the app i would like to use new fresh data from json.


#4

I think that’s a misuse of storage. Storage is for persisting things across app restarts; if all you need to do is to have it available in several distinct pages, a shared service will work just fine.

From the app’s POV, there’s no difference between “open the app” and “restart the app”, so expecting different things to happen in those two cases is weird. I still think you don’t really want to be dealing with storage at all, which will make your problem go away while reducing your complexity.


#5

Do you have an example for me to Storage temporary The data or an example for shared data?


#6

This is very stripped-down, but shows the basic idea. More here.

export class EventsService {
  events: Event;
}

export class Backend {
  constructor(private _http: Http, private _evts: Events) {
    this.refresh();
  }

  refresh(): void {
    this._http.get('url').subscribe((rsp) => {
      this._evts.events = rsp.json();
    });
  }
}

@Component()
export class TypicalPage {
  constructor(public eventService: EventService) {
  }
}

<ion-list>
  <ion-item *ngFor="event of eventService.events"></ion-item>
</ion-list>

#7

Thank you for support.
It’s not clear to me one thing.

this is my home page

and i get the data from json file with call http

Now if I click on one of this pages

and right after I click again on home page i would like that the data is present locally and not get data from json file with call http.

If you clarify me this situation It would be very important to me.

Thank you again!


#8

I’m sorry that I don’t really understand what isn’t clear to you, but if you inject a service (what I have called EventsService here) in one place, and set things in it, you can inject it similarly in any page and retrieve that data.


#9

Ok now i create a providers service to get the data
Now i have an other problem with the refresher.

this is the function for get data in the file get-data.ts

get_partners(loading) {

  if (this.data) {
    return Promise.resolve(this.data);
  }

  return new Promise(resolve => {
    this.loading.present();
    this.http.get('http://www.cinemairis.it/wp-json/wp/v2/partners')
    .map(res => res.json())
    .subscribe(data => {
          console.log("SONO QUI");
      this.data = data.results;
      this.loading.dismiss();
      resolve(this.data);
      },
      error => {
          console.log(error);
          setTimeout(() => {
            let alert = this.alertCtrl.create({
              title: "Nessuna Connessione",
              subTitle: "Si prega di riprovare",
              buttons: ["OK"]
            });
            alert.present();
            this.loading.dismiss();
          }, 1000);
          console.log(error);// Error getting the data
        });
    });
  }

and this is the function that call this in the file partners.ts

get_partners(){
  this.getData.get_partners(this.loading)
    .then(data => {
      this.items = data;
      console.log("OGGETTI" + this.items);
    });
  }

Now if i would like to use the refresh for update the data how can i do it?

  doRefresh(refresher) {

  }

#10

I really dislike the way get_partners is structured (even though I realize it is a very common idiom on these forums). If you get rid of the needless promises, you will get your refresh function for free:

partners: ReplaySubject<Event[]> = new ReplaySubject<Event[]>(1);

refresh(): void {
  let loading = this._loadings.create({});
  this.http.get('url').finally(() => {
    loading.dismiss();
  }).subscribe((rsp) => {
    this.partners.next(rsp.json().results);
  }, (err) => {
  });
}

Anywhere that needs access to the data need only subscribe to partners. If it makes sense for your app, you can call refresh in that service’s constructor in order to prime the data.


#11

Ok thanks you’re right but for me isn’t simple this code.

I don’t understand your exposition

In the providers service which code I write for create a promise that I call in the partners.ts page?

Start from here if you have the patience for support me

Many thanks :slight_smile:


#12

No promises are needed. Just expose a Subject in your service as in my previous post. The refresh method will update it with data from the server, and can be called as many times and as often as you wish from anywhere. A simple consumer page would look like this:

events: Event[] = [];

constructor(private upstream: PartnersService) {
  upstream.partners.subscribe((events) => {
    this.events = events;
  });
}

<div *ngFor="let event of events">{{event.name}}</div>

If you want to make it fancier, you can have a loader showing when events has zero length, and do your subscribing in ionViewWillEnter and tear it down in ionViewWillLeave. You could even eliminate events and just use an AsyncPipe on upstream.partners, but I prefer having it as an implementation buffer.