Nidhish
Nidhish

Reputation: 361

How to save uploaded image to IndexedDB Javascript

Am using file upload controller to browse images and the selected images should be previewed in the page as image thumbnails.

<input type="file" id="imageSelector" multiple="multiple" />

var uploadImageCtrl = document.querySelector('#imageSelector');
uploadImageCtrl.addEventListener('change', function () {
    var files = this.files;
    for(var i=0; i<files.length; i++){
        preview(this.files[i]);
    }
}, false);  

After selecting few images, go to next page and do some action. And when going back from that page, all the image previews should be there. I thought of saving these images to IndexedDB, before going to next page. But am not sure how to code for IndexedDB in this case.

Can anyone help me?

Upvotes: 4

Views: 2143

Answers (1)

Joshua Bell
Joshua Bell

Reputation: 8337

File objects are cloneable and can be saved to Indexed DB, either as records on their own or as part of other records.

This example just saves an array of files as a single record (key is "key") to an object store named "images":

// Call with array of images; callback will be called when done.
function save(array_of_files, callback) {
  openDB(function(db) {
    var tx = db.transaction('images', 'readwrite');
    tx.objectStore('images').put(array_of_files, 'key');
    tx.oncomplete = function() { callback(); };
    tx.onabort = function() { console.log(tx.error); };
  });
}

// Callback will be called with array of images, or undefined
// if not previously saved.
function load(callback) {
  openDB(function(db) {
    var tx = db.transaction('images', 'readonly');
    var req = tx.objectStore('images').get('key');
    req.onsuccess = function() {
      callback(req.result);
    };
  });
}

function openDB(callback) {
  var open = indexedDB.open('my_db');
  open.onupgradeneeded = function() {
    var db = open.result;
    db.createObjectStore('images');
  };
  open.onsuccess = function() {
    var db = open.result;
    callback(db);
  };
  open.onerror = function() { console.log(open.error); };
}

One possible gotcha: HTMLInputElement's files is not an Array itself but an array-like type called FileList. You can convert it to an array with e.g. Array.from(e.files), but a FileList can be cloned (and therefore stored in IDB) so this should "just work".

Upvotes: 5

Related Questions