IonicStorage get() not working


#1

I’m (trying) to use the IonicStorageModule in my project but can’t seem to get it working properly. I’ve followed the instructions at: https://ionicframework.com/docs/storage/ and my set and get code look like:

  addStamp(stamp): void {
    this.storage.set(stamp, true);
  }
   /* In the provider: */ 
   return new Promise((resolve, reject) => {
        this.storage.ready()
                    .then(() => {
                      this.storage.get(stamp).then((val) => {
                        resolve(val != null);
                      });
                    });
    });

    /* On the page */
  getStamp(stamp) {
    this._passport.getStamp(stamp)
                  .then((val) => {
                    return val;
                  })
                  .catch((error) => {
                    // Handle error
                  })
  }

Looking in the console on Chrome I can see the data being stored:

But if I log the value being returned by the getStamp() function in the provider I get a null value. Can anyone identify where I’m going wrong? Thank you!


#2

Three major problems:

  1. you’re needlessly instantiating an extra Promise
  2. you’re trying to turn asynchronous actions into synchronous ones, which makes no sense
  3. you failed to declare return value types for your methods, which would have helped you catch what is happening in #2

#3

Okay I think I understand, I’ve made the following changes and still no luck:

In the provider:

  addStamp(stamp): void {
    this.storage.set(stamp, true);
  }

  getStamp(stamp): boolean {
    this.storage.get(stamp)
                .then((val) => {
                  return (val != null);
                });
  }

On the page:

  addStamp(stamp): void {
    this._passport.addStamp(stamp);
  }

  getStamp(stamp): boolean {
    return this._passport.getStamp(stamp);
  }

I’m still trying to get my head round asynchronous code (my day job involves working with matlab where synchronous code is the norm) so if you could give any advice I’d appreciate it.


#4

Did you actually try building this? I get:

error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

…and this is exactly why I keep recommending people go through this exercise. When you give proper types to everything in your code, you are frequently forced to confront fundamental misunderstandings, and this is one of them.

getStamp() doesn’t return a boolean (although I appreciate that you wish it would). Moreover, there is simply no way for you to write it so that it will. When you start out with a future (be it Promise or Observable), you have to return a future. You can transform it, but you can’t make it synchronous. So:

getStamp(stamp: string): Promise<boolean> {
  return this.storage.get(stamp)
    .then(val => !!val));
}

This is literally what you were doing, with the use of the double-negation operator (!!) overcoming some of the bizarreness in JavaScript surrounding null, undefined, type conversion, and comparison operators. You probably don’t really want this, though. You probably want to pass the actual value stored under stamp to the page, not simply whether one exists or not. In that case, it is even simpler:

getStamp(stamp: string): Promise<string> {
  return this.storage.get(stamp);
}

…meanwhile, back in the page,

this.stamps.getStamp(stamp).then(sval => {
  // only in here is `sval` reliable.
  // we can do things like assign it to a controller property
  this.stamp = sval;
  // and that would be reflected in the template automatically
  // in an expression like {{stamp}}
});

#5

I finally get it! Thank you! I need to get out of the synchronous frame of mind by the sounds of things. Hopefully some more practice and I’ll get there but I’m finally starting to understand the fundamental concepts. Thank you, I really appreciate it.