Image

progressive-web-apps-vue-3

4 min read
Last update: December 19, 2021

Deleting Data from IndexedDB

Now that we know how to save and update data, it’s time for us to learn how to do the opposite action: deleting data!

Setup basic database scaffold

To start, let’s open up App.js and add a new method called deleteTodo to it. We’ll be using a similar scaffold to our saveTodo method we created in the last lesson, where we pass in an argument of todo and create an async function that returns a JavaScript Promise.

📄 App.vue

export default {
// Other code excluded for brevity
methods: {
async deleteTodo(todo) {
this.database = await this.getDatabase()

return new Promise((resolve, reject) => {

})
}
}
}

Initiate a readwrite transaction with the database

Since we also need to modify the data Congratulations in this lesson, you’ve learned how to delete item from your index DB database. And now your users are empowered to both save and delete data from your progressive web apps.

📄 App.vue

export default {
// Other code excluded for brevity
methods: {
async deleteTodo(todo) {
this.database = await this.getDatabase()

return new Promise((resolve, reject) => {
let transaction = this.database.transaction('todos', 'readwrite')
})
}
}
}

Add an item to the object store

Now that we have the right permissions, we can access and save our store using the same objectStore as the last lesson. And then, in order to delete data, IndexedDB has a function aptly named delete. And all we need to do to use it as pass in the id of our todo item and it will remove the data as we want.

📄 App.vue

export default {
// Other code excluded for brevity
methods: {
async deleteTodo(todo) {
this.database = await this.getDatabase()

return new Promise((resolve, reject) => {
const transaction = this.database.transaction('todos', 'readwrite')

// Access the todos object store
const store = transaction.objectStore('todos')

// Delete the item to the store
store.delete(todo.id)
})
}
}
}

Wrapping up our promises

Now that we’ve set everything up, we just need to wrap up our promises just like before with the oncomplete and onerror lifecycle methods.

📄 App.vue

export default {
// Other code excluded for brevity
methods: {
async saveTodo(todo) {
this.database = await this.getDatabase()

return new Promise((resolve, reject) => {
const transaction = this.database.transaction('todos', 'readwrite')
const store = transaction.objectStore('todos')

// Delete the item to the store
store.delete(todo.id)

// Resolve the promise if the transaction succeeds
transaction.oncomplete = () => {
resolve('Item successfully deleted.')
}

// Reject the promise if the transaction fails
transaction.onerror = event => {
reject(event)
}
})
}
}
}

Alright! With this, we are now ready to integrate it into our TodoMVC features.

Integrate deleteTodo into todo deletion

There are two primary features of deletion in the TodoMVC.

  • Remove single todo
  • Remove all completed todos

So let’s start by taking care of the simplest one, which is removing a single todo item.

Remove single todo

If we look through our code in App.vue, we’ll find that there is a removeTodo function that is splicing out the item from the array of todos. So, this looks like the perfect place to also add our deleteTodo method so that the database is updated at the same time!

📄 App.vue

removeTodo(todo) {
const index = this.todos.indexOf(todo)
this.todos.splice(index, 1)
this.deleteTodo(todo)
},

To verify that this works, let’s go ahead and delete a couple of items and refresh the page. If everything works, the tasks should not come back. And to double check, we can open up the Application tab in the DevTools to verify that our data indeed has been updated in IndexedDB.

Remove all completed todos

The last thing we need to update for our app is the ability to remove all todos that are completed. And we can do this by modifying the removeCompleted method. However, something we’ll notice is that this method is already leverage a filter method which automatically loops through everything. As a result, we can take advantage of this to go ahead and delete any item that is completed while allowing the filter to still return anything that is still incomplete.

removeCompleted() {
this.todos = this.todos.filter(item => {
if (item.completed) {
this.deleteTodo(item)
} else {
return !item.completed
}
})
},

And once we update the code here, you should see that everything works as you expect!

Next Steps

Congratulations! In this lesson, you’ve learned how to delete items from an object store in an IndexedDB database. And with that, your users are now empowered to both save and remove data from their app as they desire in your PWAs as well. Great job!