📜 ⬆️ ⬇️

LocalForage: Mozilla Cross-browser Local Storage

For quite some time now, web applications have the opportunity to store part of data or files locally. You can even cache MP3 files . Browsers have learned to store large amounts of data. However, so far local storage technologies are highly fragmented.

localStorage provides only the most basic functions, this storage is rather slow and does not know how to store blobs. IndexedDB and WebSQL are asynchronous, fast, and support large amounts of data, but their API is rather confusing. In addition, neither IndexedDB nor WebSQL is supported by all major browsers, and it seems that this situation will not change in the near future.

If you need to write a web application with offline mode, and you don’t know where to start, this is for you. If you have already tried to work with local repositories, and your head was spinning around - the article is for you too. We in Mozilla have written the localForage library, which greatly simplifies the task of storing local data in any browser.
')
The development of the around - HTML5 client for Foursquare helped me to feel the hard way all the difficulties of working with local storage. Although in this article I tell you how to use localForage, maybe someone would prefer to learn real-life examples of working with it.

localForage is a very simple JavaScript library that uses an API similar to the localStorage API , with the same basic get , set , remove , clear and length methods, but has some other important improvements:


Using IndexedDB and WebSQL allows you to store much more data than localStorage. The non-blocking asynchronous API makes the application faster and more responsive, since the main flow of the application does not freeze during the execution of get/set calls. Support for promises allows you to write clean code without callback spaghetti. Of course, if you like callbacks, you can use them.

Stop talking, show how it works!


The traditional localStorage API is pretty good in many ways. It is simple, does not impose complex data structures and does not require any boilerplate code at all. For example, if you need to store the application configuration locally, you can write something like:

 //  ,      var config = { fullName: document.getElementById('name').getAttribute('value'), userId: document.getElementById('id').getAttribute('value') }; //   localStorage.setItem('config', JSON.stringify(config)); //      var config = JSON.parse(localStorage.getItem('config')); 

Note that localStorage stores all the information as strings, so you have to convert everything to serialized JSON.

Everything is very simple and logical, but you can immediately notice several problems:


Simplify life with localForage


localForage solves both of these problems using an API, very similar to the localStorage interface, but asynchronous. Compare how much simpler it is to the equivalent code for IndexedDB.

IndexedDB Code:

 // IndexedDB. var db; var dbName = "dataspace"; var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ]; var request = indexedDB.open(dbName, 2); request.onerror = function(event) { //  . }; request.onupgradeneeded = function(event) { db = event.target.result; var objectStore = db.createObjectStore("users", { keyPath: "id" }); objectStore.createIndex("fullName", "fullName", { unique: false }); objectStore.transaction.oncomplete = function(event) { var userObjectStore = db.transaction("users", "readwrite").objectStore("users"); } }; //  ,   ,      var transaction = db.transaction(["users"], "readwrite"); // -        transaction.oncomplete = function(event) { console.log("All done!"); }; transaction.onerror = function(event) { //     }; var objectStore = transaction.objectStore("users"); for (var i in users) { var request = objectStore.add(users[i]); request.onsuccess = function(event) { //         console.log(event.target.result); }; } 


LocalForage code:

 //     var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ]; localForage.setItem('users', users, function(result) { console.log(result); }); 

The code with WebSQL will be somewhat shorter than the code with IndexedDB, but it will still require much more text than with localForage.

Not only strings


Suppose you want to use locally or not only text data about a user, but also his avatar. With localForage, this is done very simply:

 //   AJAX- var request = new XMLHttpRequest(); // ,      id=1 request.open('GET', "/users/1/profile_picture.jpg", true); request.responseType = 'arraybuffer'; //   ,    request.addEventListener('readystatechange', function() { if (request.readyState === 4) { // readyState DONE //    .  localStorage   localForage.setItem('user_1_photo', request.response, function() { //  ,  . }); } }); request.send(); 

You can extract a photo from the repository with just three lines of code:

 localForage.getItem('user_1_photo', function(photo) { //  data URI   -     img. console.log(photo); }); 

Callbacks and promises


If you don't like callbacks, you can use ES6 promises. This is what the last example will look like if you rewrite it using promises:

 localForage.getItem('user_1_photo').then(function(photo) { //  data URI   -     img. console.log(photo); }); 

Of course, this is an artificial and not very obvious example. If you want to look at this style of programming in real code - here is a suitable fragment from around .

Cross-browser compatibility


localForage supports all modern browsers. IndexedDB is available in all modern browsers except Safari ((IE 10+, IE Mobile 10+, Firefox 10+, Firefox for Android 25+, Chrome 23+, Chrome for Android 32+, Opera 15+). Safari and the regular Android browser ( 2.1+) use WebSQL.

At the very least, localForage uses localStorage, so you can still store data locally, though without blobs and much more slowly. But at least data conversion to JSON strings occurs automatically in this case.

The library is still very young, some of the functionality is only planned, so join the development, send error messages and patches if you want the library to be able to do more!

Source: https://habr.com/ru/post/212709/


All Articles