How to make Ionic Storage reactive

Oleg Varaksin
3 min readApr 4, 2019

Ionic Storage offers a LocalStorage-like API and can be configured for various storage engines. It also allows to persist many types of data, e.g. strings, numbers and blobs. The default order of storage engines which are tried to be used (from top to bottom):

  • SQLite (file-based database on native devices)
  • IndexedDB
  • WebSQL
  • LocaleStorage

It depends on the availability of concret storage engine if it will be used or not. IndexedDB, as data storage in browser, should be preferred over LocaleStorage because it offers asynchronous read / write operations and doesn’t block the main thread. LocaleStorage blocks the main thread with its sync read / write operations.

For storage engines in the web, Ionic Storage is backed by LocaleForage — a well-known offline storage implementation. LocaleForage API is Promise based. If you read, write or remove values through this API, you will always get an ES6 Promise. It’s no wonder that the API of Ionic Storage is Promise based too. Sometimes though, we wish us a reactive API, especially if we develop an Angular application with RxJS. RxJS is a key player that can make the Ionic Storage API reactive. In this blog post, I will show main steps to achieve this goal. For demonstration purpose, only three values will be made persistent:

  • “authToken” — JWT Authentification-Token
  • “deviceId” — some UUID which identifies the client device.
  • “trackNumber” — number of rail track :-)

Ad-hoc solution

A quick & dirty solution is straightforward. We just have to implement a service class which communicates with Ionic Storage and reveals set-, get- und remove-operations.

This implementation doesn’t fit all use cases well.

Do it right!

Let’s do it reactive. We will start with a simple Redux-like store implemented with Angular. I’ve borrowed the idea from this brilliant blog post: State management in Angular with observable store services

BehaviorSubject keeps the last state. The state itself is a plain object with three properties.

A concrete implementation of the abstract Store class above leverages the Ionic Storage under the hood. Updating some value in the persistent store (IndexedDB or whatever) reflects in the Redux-like store.

The ready$ Promise is useful if you have to wait until all values are read from the persistent storage (we will see an example below). Let’s show some usages of this reactive store implementation (which is backed by the Ionic Storage as you could see above). The first example demonstrates a facade class which injects CoreStore. The facade is a mediator between UI components and underlying services. It decouples presentation and business / service layers. As you can see, we can grab RxJS streams from the store. Such streams can be used directly in Angular templates with async pipe.

The next example shows an Angular Guard which checks if the user is logged in or not. It reads authToken and redirects the user to the login page if the token was not set (is undefined).

The last example is a component where the user inputs the track number. It is an excerpt for the sake of simplicity.

That’s all. Have fun!

--

--

Oleg Varaksin

Thoughts on software development. Author of “PrimeFaces Cookbook” and “Angular UI Development with PrimeNG”. My old blog: http://ovaraksin.blogspot.de