How to Add Client-Side Storage with Vue Part 2

Take client-side storage to the next level with IndexedDB!

Maximilien Monteil
Feb 10 · 6 min read

Taking things further

IndexedDB overview

Old School DB

IndexedDB Concepts

Setup

$ git clone -b vuexRefactor --single-branch https://github.com/MaxMonteil/VueTodo.git
$ git clone -b indexedDB --single-branch https://github.com/MaxMonteil/VueTodo.git
$ npm install idb

Initializing IndexedDB

import { openDb } from ‘idb’const dbPromise = _ => {
if (!(‘indexedDB’ in window)) {
throw new Error(‘Browser does not support IndexedDB’)
}
return openDb(‘VueTodoDB’, 1, upgradeDb => {
if (!upgradeDb.objectStoreNames.contains(‘todos’)) {
upgradeDb.createObjectStore(‘todos’)
}
if (!upgradeDb.objectStoreNames.contains(‘completed’)) {
upgradeDb.createObjectStore(‘completed’)
}
})
}

Managing Data

Saving to Storage

const saveToStorage = async (storeName, tasks) => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, ‘readwrite’)
const store = tx.objectStore(storeName)
store.put(tasks, storeName) return tx.complete
} catch (error) {
return error
}
}

Checking Storage

const checkStorage = async storeName => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, ‘readonly’)
const store = tx.objectStore(storeName)
return store.get(storeName)
} catch (error) {
return error
}
}

export default {
checkStorage,
saveToStorage
}

Making it all work

import ls from ‘./api/localStorageService’
import idbs from ‘./api/indexedDBService’
export default new Vuex.Store({
actions: {
checkStorage ({ state, commit }) {
state.dataFields.forEach(async field => {
try {
let data = await idbs.checkStorage(field)
// IndexedDB did not find the data, try localStorage
if (data === undefined) data = ls.checkStorage(field)
// LocalStorage did not find the data, reset it
if (data === null) data = []
commit(‘setState’, { field, data })
} catch (e) {
// The value in storage was invalid or corrupt so just set it to blank
commit(‘setState’, { field, data: [] })
}
})
},
async saveTodos ({ state }) {
try {
await Promise.all(state.dataFields.map(field => {
return idbs.saveToStorage(field, state[field]))
})
} catch (e) {
state.dataFields.forEach(field => {
return ls.saveToStorage(field, state[field])
})
}
}
}
})

Bringing it all Together

Maximilien Monteil

Written by

My goal is to solve problems people face with beautiful, practical, and useful solutions. I’m driven to apply and share what I learn.