<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Miguel Manjarres</title>
    <description>The latest articles on DEV Community by Miguel Manjarres (@devtony101).</description>
    <link>https://dev.to/devtony101</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F407882%2F0517a276-686b-4ee7-8757-51d24b1d5069.jpg</url>
      <title>DEV Community: Miguel Manjarres</title>
      <link>https://dev.to/devtony101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devtony101"/>
    <language>en</language>
    <item>
      <title>Introducing 'firebaseauth' Spring Boot Library</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Sat, 03 Jun 2023 16:46:27 +0000</pubDate>
      <link>https://dev.to/devtony101/introducing-firebaseauth-spring-boot-library-1ini</link>
      <guid>https://dev.to/devtony101/introducing-firebaseauth-spring-boot-library-1ini</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;How many times have you struggled with setting up security in your Spring Boot API? Well those days are over now that you can use the &lt;code&gt;firebaseauth&lt;/code&gt; library to take care of that.&lt;/p&gt;

&lt;p&gt;By following a simple set of steps you can have an API secured with Firebase in a matter of minutes! You won't have to deal with custom filters, exceptions or the Firebase SDK for that matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;When I first started to develop APIs with Firebase I struggled on how to set it up within Spring Boot since the documentation available was a little obfuscted, with this library I hope to help anyone that may have the same problems that I had. The project's README file has all you need to do in order to have a working, secured Spring Boot API.&lt;/p&gt;

&lt;p&gt;If you are interested I would gladly appreciate that you leave a star in the project's repo here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101" rel="noopener noreferrer"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/firebaseauth" rel="noopener noreferrer"&gt;
        firebaseauth
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Spring-Boot library to abstract API authentication with Firebase
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Firebase Auth &lt;a href="https://github.com/DevTony101/firebaseauth/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4a41915272d110c2e82ba6306a32da95e3f371fbccf3016ed305f81842283f88/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f646576746f6e793130312f6669726562617365617574683f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;If you need to protect your Spring Boot API with the help of Firebase quickly and stress-free then this is the library for you
It will provide you with a simple yet powerful implementation to receive and decode a Firebase token and to put that information available
in Spring's own security context.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/firebaseauth#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#implementing-security-configuration" rel="noopener noreferrer"&gt;Implementing security configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#setting-firebase-configuration" rel="noopener noreferrer"&gt;Setting Firebase configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#testing" rel="noopener noreferrer"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#about-roles" rel="noopener noreferrer"&gt;About roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#example" rel="noopener noreferrer"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/firebaseauth#about" rel="noopener noreferrer"&gt;About&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#why-should-you-use-this-library" rel="noopener noreferrer"&gt;Why should you use this library?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/firebaseauth#faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Quick and seamless security setup for your API&lt;/li&gt;
&lt;li&gt;CORS configuration and 401 error validations are already taken care of&lt;/li&gt;
&lt;li&gt;The information obtained from the decoded firebase token is put directly in the security context with a default role if one hast not been provided by the token (more of that later!)&lt;/li&gt;
&lt;li&gt;You won't need to manually read your firebase configuration file&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Getting started&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Before starting you need to make…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevTony101/firebaseauth" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Thank you so much for reading! See you next time.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>java</category>
      <category>springboot</category>
      <category>opensource</category>
    </item>
    <item>
      <title>¡Gasteroids! 👾 + ☄️</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Mon, 22 Nov 2021 05:10:16 +0000</pubDate>
      <link>https://dev.to/devtony101/gasteroids--57f9</link>
      <guid>https://dev.to/devtony101/gasteroids--57f9</guid>
      <description>&lt;p&gt;Hi there! 👋🏼&lt;br&gt;
This weekend I decided to take a break from coding... by coding a mini-game! Yeah I know that isn't exactly "taking a break", but it was actually pretty fun to make.&lt;/p&gt;

&lt;p&gt;I originally wanted to make something similar to Galaga, but the work that would have required would have defeated the purpose of the whole activity, so I made asteroids as the "enemies" instead, hence the name of the game.&lt;/p&gt;

&lt;p&gt;Here's the end result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5X6DVT93--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1o67op3bykimgyyc8n8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5X6DVT93--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1o67op3bykimgyyc8n8.gif" alt="game_gif" width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both the code and the game itself are uploaded to &lt;strong&gt;GitHub&lt;/strong&gt; so head over there if you want to take a look!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/gasteroids"&gt;
        gasteroids
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple javascript game inspired by Galaga and Asteroids. Made using p5.js
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Gasteroids 👾 + ☄️
&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/DevTony101/gasteroids/blob/main/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/178aa503732cb341f674f71f661c860c1cb3604d09d32d56f88a036894d501e2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e7376673f7374796c653d666c61742d737175617265" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/67a6fba1d666a2b62137bc102477764ab0c7b7472fa68e2914b50a553cb1ea2f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6164652532305573696e672d50354a532d70696e6b3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/67a6fba1d666a2b62137bc102477764ab0c7b7472fa68e2914b50a553cb1ea2f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6164652532305573696e672d50354a532d70696e6b3f7374796c653d666c61742d737175617265" alt="Made Using: P5JS"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Preamble&lt;/h2&gt;
&lt;p&gt;A mysterious horde of asteroids had been released upon Earth and unleashed terror among its inhabitants. You, an awarded space commander, had been chosen to protect Earth by destroying all the asteroids before they hit the planet!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Play &lt;a href="https://devtony101.github.io/gasteroids/" rel="nofollow"&gt;here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
Game mechanics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your misssion&lt;/strong&gt;: Destroy as many asteroids as you can! If an asteroid goes past the bottom border of your screen you will lose a heart point! The number of heart points you start the game with are conditioned by the game's difficulty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moving&lt;/strong&gt;: You can move your ship by moving the mouse along the x-axis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shooting&lt;/strong&gt;: You can activate your laser gun by clicking on the screen or pressing the space bar. The number of "bullets" you can fire at a given time is conditioned by the game's difficulty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exiting the game&lt;/strong&gt;: You can press the &lt;strong&gt;[ESC]&lt;/strong&gt; key at…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevTony101/gasteroids"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Comment down below what your final score was! &lt;br&gt;
Can you beat mine of 6720? 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvements
&lt;/h2&gt;

&lt;p&gt;The game was made using &lt;strong&gt;p5.js&lt;/strong&gt;, and the code isn't too complex (I hope), so if you are a beginner who is looking for some fun project to work with or you just have some hours to spare, here's a list of improvements you could make to this game:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make the spaceship explode when an asteroid hit it&lt;/li&gt;
&lt;li&gt;Give the spaceship some special super-power based on the score&lt;/li&gt;
&lt;li&gt;Give the spaceship an extra-live based on the score&lt;/li&gt;
&lt;li&gt;Give the spaceship some powerup by exploding an "special item"&lt;/li&gt;
&lt;li&gt;Add a bossfight (A big asteroid that requires a set number of hits maybe?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can clone the repo so you can add this features and, if you'd like your changes to be in the main game, you can make a pull request.&lt;/p&gt;

&lt;p&gt;Thank you for reading! If you have comments and/or suggestions to make, please leave them down below.&lt;/p&gt;

&lt;p&gt;See you next time 👋🏼&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Vue Clean Celebrates Its First 10K Downloads</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Mon, 15 Feb 2021 15:45:54 +0000</pubDate>
      <link>https://dev.to/devtony101/vue-clean-celebrates-its-first-10k-downloads-4ln</link>
      <guid>https://dev.to/devtony101/vue-clean-celebrates-its-first-10k-downloads-4ln</guid>
      <description>&lt;p&gt;When I started developing with Vue I often found myself doing the same steps everytime I wanted to set up a new project. As developers we want to automate as much as possible to reduce errors, and so the idea for this plugin came up to my mind.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if I build a script to delete all the unnecessary files and download the right dependencies to my project? That's nice, but what if there are other developers who are struggling with this same problem?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Immediately after thinking this I went to the Vue documentation about how to build a custom Vue CLI plugin, and deployed the first stable version of Vue Clean back in September, 2020.&lt;/p&gt;

&lt;p&gt;Today, Vue Clean has &lt;strong&gt;10K&lt;/strong&gt; downloads on &lt;strong&gt;npm&lt;/strong&gt; with an average of &lt;strong&gt;2.2K downloads per month&lt;/strong&gt;, and all I can say is &lt;strong&gt;¡THANK YOU!&lt;/strong&gt; 🙌🏼. And  If you haven't download it yet, please give it a chance, I would love to hear your feedback. (Also don't forget to give it a star ⭐ while you are at it).&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean"&gt;
        vue-cli-plugin-clean
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A plugin that helps you bootstrap your Vue application by doing some common configurations.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Vue CLI Plugin Clean&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean/blob/master/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/87ed8c0278809b626e9bfa99e2f010e2551d3e8a3bc0eaae0c3542c42ddaeb37/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/dd610516711004cc573e51eaf700bb72e2881eee681c4364f0ccfe7a51040131/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="version"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4a154f998bf6f075b69ed03c2b5bf57542dbd3415bb5a34c0c9e4a130588f540/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean"&gt;&lt;img src="https://camo.githubusercontent.com/19bcf75e82a3cdfa3e768d4a79f2b1a28fad0450e141ae8ad2e2188b7ae17229/68747470733a2f2f696d672e736869656c64732e696f2f64617669642f646576746f6e793130312f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d646570656e6461626f74" alt="dependencies"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4d9809e6c4133d11f1f658def5f097960d8e790ad3dee91751e0ba1035447a99/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f7675652d636c692d706c7567696e2d636c65616e3f636f6c6f723d726564266c6162656c3d746f74616c253230646f776e6c6f616473266c6f676f3d6e706d267374796c653d666c61742d737175617265" alt="total downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Vue 2.x plugin that helps you bootstrap your application by performing some common configurations.&lt;/p&gt;
&lt;h1&gt;
Table of Contents&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#features"&gt;Features&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#general"&gt;General&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#support-for-base-components"&gt;Support for base components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#prettier-configuration"&gt;Prettier configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#automatic-import-for-vuex-modules"&gt;Automatic import for Vuex modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#usage"&gt;Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#getting-started"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#using-the-baseicon-component"&gt;Using the BaseIcon component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#using-the-basec-command"&gt;Using the &lt;code&gt;basec&lt;/code&gt; command&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#using-basec-through-npm-scripts"&gt;Using &lt;code&gt;basec&lt;/code&gt; through NPM scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#using-basec-through-the-vue-ui"&gt;Using &lt;code&gt;basec&lt;/code&gt; through the Vue UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#about"&gt;About&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#why-should-you-use-this-plugin"&gt;Why should you use this plugin?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/DevTony101/vue-cli-plugin-clean/master/#faq"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Features&lt;/h2&gt;
&lt;h3&gt;
General&lt;/h3&gt;
&lt;p&gt;The main goal of this plugin is to quickly set up a project by deleting some files and components created by the Vue CLI service. By default this plugin will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;components&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;views&lt;/code&gt; folder except the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;router/index.js&lt;/code&gt; file to only include the route to the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;App.vue&lt;/code&gt; file to remove all the boilerplate code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Support for base components&lt;/h3&gt;
&lt;p&gt;This an opt-in feature that you can enable when installing…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevTony101/vue-cli-plugin-clean"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;While we are here I want to show two new features Vue Clean has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-export Vuex Modules&lt;/strong&gt;: If you work with Vuex, you know the hassle of creating modules and importing them in the Vuex instance for every module you create. As per version &lt;strong&gt;v0.5.0&lt;/strong&gt; Vue Clean comes shipped with a script that auto-import all modules inside the &lt;code&gt;vuex/&lt;/code&gt; folder, so you can focus on what really matters, the code!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Props for the BaseButton component&lt;/strong&gt;: If you have been working with the base button template, you'll be glad to know that now the component includes props for controlling the &lt;em&gt;width&lt;/em&gt; and &lt;em&gt;height&lt;/em&gt; of the button. This feature was introduced in version &lt;strong&gt;v0.5.1&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading this far! I'm excited to see what awesome projects you can do with the help of Vue Clean.&lt;/p&gt;

&lt;p&gt;See you next time 👋🏼.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>showdev</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing Vue Clean v0.4.1</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Sat, 19 Dec 2020 22:00:53 +0000</pubDate>
      <link>https://dev.to/devtony101/introducing-vue-clean-v0-4-1-4np4</link>
      <guid>https://dev.to/devtony101/introducing-vue-clean-v0-4-1-4np4</guid>
      <description>&lt;p&gt;A while ago I announced &lt;strong&gt;Vue Clean&lt;/strong&gt;, a tool for Vue developers and today I'm happy to announce that version 0.4.1 is up and ready to use!&lt;/p&gt;

&lt;p&gt;But, what is Vue Clean exactly?&lt;/p&gt;

&lt;h2&gt;
  
  
  About Vue Clean
&lt;/h2&gt;

&lt;p&gt;When I started in Vue, I always had to do the same steps everytime I wanted to create a new project: delete the same components, install the same dependencies, write the same boilerplate code. And I thought to myself "there's got to be some better way to do this" and like every developer, I created my own solution: &lt;strong&gt;Vue Clean&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vue Clean is a Vue CLI plugin that takes care of all the hassle of starting a new project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It deletes all the components generated by the vue-cli&lt;/li&gt;
&lt;li&gt;It deletes all the views generated by the vue-cli except the &lt;code&gt;Home.vue&lt;/code&gt; file (for obvious reasons)&lt;/li&gt;
&lt;li&gt;It deletes all the boilerplate code inside the &lt;code&gt;App.vue&lt;/code&gt; file and replace it with the minimal to function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's not all! Vue Clean also helps you with one important part of the Vue development workflow: &lt;strong&gt;Base Components&lt;/strong&gt;, if you want to know how, head to the GitHub repository page (down below).&lt;/p&gt;

&lt;p&gt;The main goal of Vue Clean is to be the perfect tool for beginners in Vue and even to be a convenient tool for experts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in this version?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Drop support for Tailwind
&lt;/h3&gt;

&lt;p&gt;In previous versions Vue Clean had an option to create the configuration files for Tailwind (that was another step I had to do in every project), but it turns out there's already a &lt;a href="https://github.com/forsartis/vue-cli-plugin-tailwind" rel="noopener noreferrer"&gt;good, well-document plugin&lt;/a&gt; that does exactly that so, why reinvent the wheel? Vue Clean dropped support for Tailwind in version &lt;strong&gt;0.2-alpha&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing the &lt;code&gt;basec&lt;/code&gt; command
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;basec&lt;/code&gt; is a vue-cli command created by Vue Clean when you install it. With it, you can create base components &lt;strong&gt;directly from the command line&lt;/strong&gt;. Not only that but you can create them using &lt;em&gt;templates&lt;/em&gt; for when you need to quickly prototype a view. The &lt;code&gt;basec&lt;/code&gt; command was introduced in version &lt;strong&gt;0.3.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Creating base components has never been so easy!&lt;/p&gt;

&lt;h3&gt;
  
  
  New and better documentation
&lt;/h3&gt;

&lt;p&gt;The instructions in the &lt;code&gt;README&lt;/code&gt; file now include examples of use with a better and more understandable structure.&lt;/p&gt;

&lt;p&gt;Now go and give it a try!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101" rel="noopener noreferrer"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;
        vue-cli-plugin-clean
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A plugin that helps you bootstrap your Vue application by doing some common configurations.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Vue CLI Plugin Clean&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/75babf42d06e96ac4102eed88bef14caa155b46777c0238d32e7013e1656fb61/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a54619b7731453662f67df87d10ca9c04e7e5224dd04ae17b0dd3d9919610ea1/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="version"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/02be4d7c2631c975da3e4324d8f8886ec66e5df081261efb7d56f1d5a98db73d/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/491df39e606123a61f0237966b3e3ee5702f45e889013e1606aea674edd98609/68747470733a2f2f696d672e736869656c64732e696f2f64617669642f646576746f6e793130312f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d646570656e6461626f74" alt="dependencies"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4fde5d85674f64137442c0a0d43ea6d6fc237d4041d04d9879fd58efaa61b255/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f7675652d636c692d706c7567696e2d636c65616e3f636f6c6f723d726564266c6162656c3d746f74616c253230646f776e6c6f616473266c6f676f3d6e706d267374796c653d666c61742d737175617265" alt="total downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Vue 2.x plugin that helps you bootstrap your application by performing some common configurations.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of Contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#general" rel="noopener noreferrer"&gt;General&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#support-for-base-components" rel="noopener noreferrer"&gt;Support for base components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#prettier-configuration" rel="noopener noreferrer"&gt;Prettier configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#automatic-import-for-vuex-modules" rel="noopener noreferrer"&gt;Automatic import for Vuex modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-the-baseicon-component" rel="noopener noreferrer"&gt;Using the BaseIcon component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-the-basec-command" rel="noopener noreferrer"&gt;Using the &lt;code&gt;basec&lt;/code&gt; command&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-basec-through-npm-scripts" rel="noopener noreferrer"&gt;Using &lt;code&gt;basec&lt;/code&gt; through NPM scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-basec-through-the-vue-ui" rel="noopener noreferrer"&gt;Using &lt;code&gt;basec&lt;/code&gt; through the Vue UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#about" rel="noopener noreferrer"&gt;About&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#why-should-you-use-this-plugin" rel="noopener noreferrer"&gt;Why should you use this plugin?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;General&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The main goal of this plugin is to quickly set up a project by deleting some files and components created by the Vue CLI service. By default this plugin will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;components&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;views&lt;/code&gt; folder except the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;router/index.js&lt;/code&gt; file to only include the route to the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;App.vue&lt;/code&gt; file to remove all the boilerplate code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Support for base components&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;This an opt-in feature that you can enable when installing…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you find Vue Clean useful please consider giving it a star ⭐ on GitHub! It's the best way to support and ensure future versions will be released.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>P5.JS: Polar Mandalas</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Tue, 08 Dec 2020 19:50:30 +0000</pubDate>
      <link>https://dev.to/devtony101/p5js-polar-mandalas-1kc0</link>
      <guid>https://dev.to/devtony101/p5js-polar-mandalas-1kc0</guid>
      <description>&lt;p&gt;Hi there 👋! In this unplanned series about P5JS projects I had archived I now present to you: Polar Mandalas!&lt;/p&gt;

&lt;p&gt;The code uses the concept of &lt;strong&gt;polar coordinates&lt;/strong&gt; to make beautiful and colorful lines across your page. All the magic happens on the &lt;strong&gt;Body&lt;/strong&gt; class, it has the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;radius&lt;/strong&gt;: It's the distance between a single body and the center of the page (by convention, the cartesian plane for the canvas has its origin in the top-left corner of the page, here I've translated to the center to reduce the complexity of calculations). The variation of the radius it's what makes the drawings. Its initial value it's given as an argument for the constructor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;velocity&lt;/strong&gt;: The velocity at which the body moves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;angle&lt;/strong&gt;: It's the angle at which the body is respect to the x-axis. It increments proportional to the velocity, that is, the more velocity the body has, the more curved the lines will be. The angle grows indefinitely and its initial value it's given as an argument for the constructor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;alpha, beta&lt;/strong&gt;: Constants values defined randomly at construction. It defines the ratio at which the radius varies according to the following function: &lt;em&gt;alpha + cos(beta * angle)&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;clr&lt;/strong&gt;: The color of the body and therefore the color of the trace (the line it draws).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;history&lt;/strong&gt;: An array of previous points that the code uses to draw the trace itself.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can interact with the code right here (press enter to create a new set of bodies):&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Dev_Tony/embed/eYdzqBN?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This project was based on a &lt;a href="https://www.youtube.com/watch?v=f5QBExMNB1I"&gt;coding challenge&lt;/a&gt; made by &lt;strong&gt;Daniel Shiffman&lt;/strong&gt; about Mathematical Rose Patterns.&lt;/p&gt;

&lt;p&gt;I hope you liked it! If you have questions or suggestions to make please leave them down below. Thanks 👏!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>P5.JS: Interactive Clock</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Sat, 28 Nov 2020 21:08:24 +0000</pubDate>
      <link>https://dev.to/devtony101/p5-js-interactive-clock-4afc</link>
      <guid>https://dev.to/devtony101/p5-js-interactive-clock-4afc</guid>
      <description>&lt;p&gt;Hi there 👋! In this post I want to share an old project of mine that I have archived on GitHub and decided to re-do it again: Fleeing Points Clock!&lt;/p&gt;

&lt;p&gt;An interactive clock made of little squares that are actually &lt;em&gt;steering vehicles&lt;/em&gt;, that is, entities that experiment a certain &lt;em&gt;desire&lt;/em&gt; to go to a certain place, and as a consequence to that desire the vehicle experiments a force that drags it towards its target. It's a very interesting concept that I learned while watching Daniel Shiffman's Coding Challenge: &lt;a href="https://www.youtube.com/watch?v=4hA7G3gup-4" rel="noopener noreferrer"&gt;Steering Behaviors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is how the clock looks like, it was built using &lt;strong&gt;P5.js&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhatvr4ougi3y1wkxp63j.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhatvr4ougi3y1wkxp63j.gif" alt="Gif_1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, passing your mouse over the numbers produces an opposite force that repels the vehicles but, as soon as the cursor leaves, the squares rearrange themselves.&lt;/p&gt;

&lt;p&gt;You can also change the colors of the squares by pressing "ENTER":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnd8l19ae3e6n2ywkfaeg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnd8l19ae3e6n2ywkfaeg.gif" alt="Gif_2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to try it yourself, you can visit the page &lt;a href="https://devtony101.github.io/fleeing-points-clock/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! And if you are curious about the code, please check out the repo (and leave a star if you wish):&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101" rel="noopener noreferrer"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/fleeing-points-clock" rel="noopener noreferrer"&gt;
        fleeing-points-clock
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A clock made of interactive, colored pieces that move when you hover with your mouse. Made using p5.js.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Hacktoberfest Completion</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Fri, 23 Oct 2020 19:24:22 +0000</pubDate>
      <link>https://dev.to/devtony101/hacktoberfest-completion-432l</link>
      <guid>https://dev.to/devtony101/hacktoberfest-completion-432l</guid>
      <description>&lt;p&gt;Today I got an email saying I completed this year Hacktoberfest 🎉! &lt;br&gt;
In this little blog post I'm gonna talk about my experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  About My Experience
&lt;/h2&gt;

&lt;p&gt;Even though I'm not completely new to GitHub and that I've already contributed to a few repositories before this event, this was my &lt;em&gt;first&lt;/em&gt; Hacktoberst and so I feeled a &lt;em&gt;rush&lt;/em&gt; whenever I entered to GitHub to search for an active repository to where I could solve an issue.&lt;/p&gt;

&lt;p&gt;It felt nice to compete in the event not only because of the prize but because the feeling of camaraderie, collaborating with other developers and mantainers alike, working towards a common goal.&lt;/p&gt;

&lt;p&gt;Also through this event I finally achieved the confidence to make a project of mine open source! I opened two issues and not more than an hour later there were two people interested in solving them! The day after that I did my first &lt;em&gt;issue review&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned From Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;I think I can summarize my learning experience in these two points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To be patient&lt;/strong&gt;. I feeled very stressed out because I couldn't find a project to contribute to, unfortunately I didn't had enough time to spend on coding so I had to set my goals a little lower, that is, contributions that didn't requiered &lt;em&gt;a lot&lt;/em&gt; of work, so being patient was key to find repositories that met my expectations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To be creative&lt;/strong&gt;. There are tons of other developers who are eager to achieve their 4 pull request too! Some of them way more experienced than I, so if I wanted to make my contribution stand out, I &lt;em&gt;had&lt;/em&gt; to be creative! And even so I couldn't keep up with all the awesome stuff other people did.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general I'm very happy with how things turned out and I hope next year I could participate in this incredible event once again. &lt;/p&gt;

&lt;p&gt;Thanks for reading 👏!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Cleaning Your Vue Project With Vue-Clean</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Thu, 17 Sep 2020 16:01:50 +0000</pubDate>
      <link>https://dev.to/devtony101/cleaning-your-vue-project-with-vue-clean-45d8</link>
      <guid>https://dev.to/devtony101/cleaning-your-vue-project-with-vue-clean-45d8</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How many times have you created a new Vue project using &lt;code&gt;vue-cli&lt;/code&gt; and then sighed when it's done because you have to delete the pre-built files and components?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How many times you had to do the same configuration for base components in all the Vue projects you created?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How many times you had to manually create configuration files for code formatters like &lt;code&gt;prettier&lt;/code&gt; or frameworks like &lt;code&gt;tailwind&lt;/code&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wouldn't be nice if you could do all this with just one command? If the answer is yes, then this &lt;code&gt;vue-cli&lt;/code&gt; plugin is for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing &lt;code&gt;vue-cli-plugin-clean&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Just like you, whenever I had to create a new Vue project, I had to repeat the same steps to get the right setup, and that included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing the same base dependencies&lt;/li&gt;
&lt;li&gt;Deleting pre-built Vue components and views&lt;/li&gt;
&lt;li&gt;Creating and modifying configuration files (&lt;code&gt;.eslintrc.js&lt;/code&gt;, &lt;code&gt;.prettierrc.js&lt;/code&gt;, etc)&lt;/li&gt;
&lt;li&gt;Configuring base components &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Soon enough I became tired and decided to automate this process, and that's when I came up with the idea for this plugin!&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;p&gt;So what does exactly this plugin does for you?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The primary goal of this plugin is to &lt;strong&gt;clean&lt;/strong&gt; your project, that is, to delete &lt;strong&gt;all&lt;/strong&gt; components and views except &lt;code&gt;Home.vue&lt;/code&gt; and &lt;code&gt;App.vue&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Even though it does not delete them, the plugin rewrites &lt;code&gt;Home.vue&lt;/code&gt; and &lt;code&gt;App.vue&lt;/code&gt; to have the minimum amount of functional code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This happens by &lt;strong&gt;default&lt;/strong&gt; but there are a set of functions that are &lt;strong&gt;optional&lt;/strong&gt; (and honestly recommended):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Base Components&lt;/strong&gt;: If you are building a complete front-end app, chances are you are using at least one component across all your project and is a good practice to group those components under a common umbrella called &lt;strong&gt;base components&lt;/strong&gt;. These base components are supposed to be &lt;strong&gt;global&lt;/strong&gt; (by definition), but in order to make Vue recognize them as such, you need to make some changes, but no need to worry, &lt;code&gt;vue-cli-plugin-clean&lt;/code&gt; does it for you!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prettier&lt;/strong&gt;: If you chose &lt;strong&gt;Prettier&lt;/strong&gt; as your code formatter, this plugin will also create a configuration file for it with two useful pre-configured options. I included Prettier because it's the tool I used the most, but I know it's not the only one and I wish that, in future versions, this plugin offers support to all those tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tailwind&lt;/strong&gt;: If for any reason, you want to use Tailwind as your CSS Framework, you may know that you need to install the necessary dependencies and create some configuration files, and while yes there are already some tools that do this thing, this plugin offers its own solution so you don't have to install any additional tools. I included Tailwind because it's the framework I used the most, but it's not the only one (there's &lt;strong&gt;Bulma&lt;/strong&gt;, for example), so I hope that, in future versions, this plugin offers support to all of them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need more information, head up to the plugin's repository here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101" rel="noopener noreferrer"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;
        vue-cli-plugin-clean
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A plugin that helps you bootstrap your Vue application by doing some common configurations.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Vue CLI Plugin Clean&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/75babf42d06e96ac4102eed88bef14caa155b46777c0238d32e7013e1656fb61/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a54619b7731453662f67df87d10ca9c04e7e5224dd04ae17b0dd3d9919610ea1/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="version"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/02be4d7c2631c975da3e4324d8f8886ec66e5df081261efb7d56f1d5a98db73d/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d6e706d" alt="downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/491df39e606123a61f0237966b3e3ee5702f45e889013e1606aea674edd98609/68747470733a2f2f696d672e736869656c64732e696f2f64617669642f646576746f6e793130312f7675652d636c692d706c7567696e2d636c65616e3f7374796c653d666c61742d737175617265266c6f676f3d646570656e6461626f74" alt="dependencies"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/vue-cli-plugin-clean" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4fde5d85674f64137442c0a0d43ea6d6fc237d4041d04d9879fd58efaa61b255/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f7675652d636c692d706c7567696e2d636c65616e3f636f6c6f723d726564266c6162656c3d746f74616c253230646f776e6c6f616473266c6f676f3d6e706d267374796c653d666c61742d737175617265" alt="total downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Vue 2.x plugin that helps you bootstrap your application by performing some common configurations.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of Contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#general" rel="noopener noreferrer"&gt;General&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#support-for-base-components" rel="noopener noreferrer"&gt;Support for base components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#prettier-configuration" rel="noopener noreferrer"&gt;Prettier configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#automatic-import-for-vuex-modules" rel="noopener noreferrer"&gt;Automatic import for Vuex modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-the-baseicon-component" rel="noopener noreferrer"&gt;Using the BaseIcon component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-the-basec-command" rel="noopener noreferrer"&gt;Using the &lt;code&gt;basec&lt;/code&gt; command&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-basec-through-npm-scripts" rel="noopener noreferrer"&gt;Using &lt;code&gt;basec&lt;/code&gt; through NPM scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#using-basec-through-the-vue-ui" rel="noopener noreferrer"&gt;Using &lt;code&gt;basec&lt;/code&gt; through the Vue UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#about" rel="noopener noreferrer"&gt;About&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#why-should-you-use-this-plugin" rel="noopener noreferrer"&gt;Why should you use this plugin?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DevTony101/vue-cli-plugin-clean#faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;General&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The main goal of this plugin is to quickly set up a project by deleting some files and components created by the Vue CLI service. By default this plugin will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;components&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Delete everything in the &lt;code&gt;views&lt;/code&gt; folder except the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;router/index.js&lt;/code&gt; file to only include the route to the &lt;code&gt;Home.vue&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Re-write the &lt;code&gt;App.vue&lt;/code&gt; file to remove all the boilerplate code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Support for base components&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;This an opt-in feature that you can enable when installing…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevTony101/vue-cli-plugin-clean" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  About the development
&lt;/h3&gt;

&lt;p&gt;This plugin's still in development (hence, there's no version &lt;code&gt;1.0.0&lt;/code&gt; just yet), but a functional version is already released (version &lt;code&gt;0.1.10&lt;/code&gt;) and it's uploaded on &lt;strong&gt;npm&lt;/strong&gt;! (this is also my first &lt;strong&gt;npm&lt;/strong&gt; package 🎉) I would love some feedback about the functionality and usefulness of the plugin, I really think this could help some beginners and even some seniors in Vue!&lt;/p&gt;

&lt;p&gt;Thank you so much for reading! I hope for your feedback! See you next time 👋.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JavaScript: Building a To-Do App (Part 4: Final)</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Mon, 03 Aug 2020 22:16:00 +0000</pubDate>
      <link>https://dev.to/devtony101/javascript-building-a-to-do-app-part-4-final-2okm</link>
      <guid>https://dev.to/devtony101/javascript-building-a-to-do-app-part-4-final-2okm</guid>
      <description>&lt;h2&gt;
  
  
  📖 Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to the last part of the "Introduction to the IndexedDB API" series. In the last post, we added an important feature to our application, the ability to &lt;em&gt;see&lt;/em&gt; the tasks on the page; we also did a little bit of refactoring as we needed to perform some actions for when the connection to the database is established. In this last part, we are going to finish our app by adding the ability to &lt;strong&gt;delete&lt;/strong&gt; any given task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;delete&lt;/code&gt; method on the &lt;code&gt;Database&lt;/code&gt; class that deletes a task given its &lt;em&gt;id&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Complete the &lt;code&gt;removeTask&lt;/code&gt; function on the &lt;code&gt;index.js&lt;/code&gt; file so that effectively delete a task when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Initial Setup
&lt;/h3&gt;

&lt;p&gt;If you want to code along (which is &lt;strong&gt;&lt;em&gt;highly recommended&lt;/em&gt;&lt;/strong&gt;), then go to the following GitHub repository:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/js-todo-app-indexed_db"&gt;
        js-todo-app-indexed_db
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a to-do web application that uses the IndexedDB API.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Once there, go to the &lt;code&gt;README.md&lt;/code&gt; file and search for the link labeled &lt;code&gt;Starting Code&lt;/code&gt; for the third (last) part. It will redirect you to a commit tagged as &lt;code&gt;starting-code-part-three&lt;/code&gt; that contains all we have done so far plus the new &lt;code&gt;delete&lt;/code&gt; function on the &lt;code&gt;Database&lt;/code&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠 Completing the &lt;code&gt;delete&lt;/code&gt; Function
&lt;/h2&gt;

&lt;p&gt;This will be pretty straight forward, the process is exactly the same as the one we did back in part two:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;transaction&lt;/code&gt; object from the database&lt;/li&gt;
&lt;li&gt;Get a reference to the &lt;code&gt;objectStore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a request based on the action you need to perform, which in this case, is to &lt;em&gt;delete&lt;/em&gt; something&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code, it would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Skipping validation of the id ...&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 1&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 2&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 3&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The key difference here, in contrast to the &lt;code&gt;persist&lt;/code&gt; function, is that we are only going to take care of the &lt;code&gt;complete&lt;/code&gt; event emitted by the transaction because, if the task was successfully deleted, we would want to remove it from the &lt;code&gt;DOM&lt;/code&gt; but, we will get to that later. &lt;/p&gt;

&lt;p&gt;Now we have to ask ourselves an important question, how we should handle see &lt;code&gt;oncomplete&lt;/code&gt; callback? There are two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We &lt;em&gt;could&lt;/em&gt; return the &lt;code&gt;transaction&lt;/code&gt; object and handle it in the &lt;code&gt;index.js&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;We &lt;em&gt;could&lt;/em&gt; pass a function as a parameter to the &lt;code&gt;delete&lt;/code&gt; function&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both are equally valid but, just because it &lt;em&gt;looks&lt;/em&gt; fancier, let's choose to do the second one, in which case, we need to change the signature of the &lt;code&gt;delete&lt;/code&gt; function so that accepts a second named argument. The rest is pretty much the same as in the &lt;code&gt;persist&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oncomplete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's all! Our &lt;code&gt;delete&lt;/code&gt; function is complete, a piece of cake 🍰, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  👨‍🔧 Assigning an &lt;code&gt;ID&lt;/code&gt; to our Tasks
&lt;/h2&gt;

&lt;p&gt;In order to use the &lt;code&gt;delete&lt;/code&gt; function, we need to have the &lt;code&gt;id&lt;/code&gt; of the task we want to delete but, because we don't know in advance which task the user is going to remove, the &lt;code&gt;id&lt;/code&gt; needs to be dynamically retrieved.&lt;/p&gt;

&lt;p&gt;A great way to accomplish this is by storing the &lt;code&gt;id&lt;/code&gt; of the task in a &lt;code&gt;data-*&lt;/code&gt; attribute inside the &lt;code&gt;message&lt;/code&gt; component. To do it, we just need to use the &lt;code&gt;setAttribute()&lt;/code&gt; method on the &lt;code&gt;message&lt;/code&gt; object in the &lt;code&gt;showTasks&lt;/code&gt; function, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// The 'id' is the key, it's stored in the value property of the cursor object alongside the other fields&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Here we store the key in a data attribute called data-id&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it! Now we are all set to start deleting stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  👨‍💻 Using the &lt;code&gt;delete&lt;/code&gt; Function
&lt;/h2&gt;

&lt;p&gt;On the &lt;code&gt;index.js&lt;/code&gt; file, let's create a new function called &lt;code&gt;removeTask&lt;/code&gt; with the following signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The event will be the message component representing the task&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function will be called from within a &lt;code&gt;button&lt;/code&gt; element that will be placed inside the &lt;code&gt;header&lt;/code&gt; of the &lt;code&gt;message&lt;/code&gt; component (according to &lt;strong&gt;Bulma´s&lt;/strong&gt; official &lt;a href="https://bulma.io/documentation/components/message/"&gt;documentation&lt;/a&gt;)&lt;sup&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Inside there, let's first retrieve the &lt;code&gt;article&lt;/code&gt; block itself from the &lt;code&gt;event&lt;/code&gt; object (remember that the &lt;code&gt;event&lt;/code&gt; only carries the node that fired up the action, in this case, the &lt;code&gt;button&lt;/code&gt; element) and then, get the actual &lt;code&gt;id&lt;/code&gt; from the &lt;code&gt;data-id&lt;/code&gt; attribute. Next, pass the &lt;code&gt;id&lt;/code&gt; to the &lt;code&gt;delete&lt;/code&gt; function we created earlier, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Success callback&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now all that's left is to figure out what to put inside the callback function. &lt;/p&gt;

&lt;p&gt;If the task is successfully deleted, then we must remove it from the &lt;code&gt;DOM&lt;/code&gt;, else the user is going to be very confused. On top of that, if there was only one task, we need to let the user know that there are no more tasks left, this is exactly what we did in the &lt;code&gt;showTasks&lt;/code&gt; function for when the &lt;code&gt;cursor&lt;/code&gt; object is not defined.&lt;/p&gt;

&lt;p&gt;So, putting it together:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Remove the task from the &lt;code&gt;DOM&lt;/code&gt;, that is, remove the message component (the &lt;code&gt;article&lt;/code&gt; block) from the &lt;code&gt;tasksContainer&lt;/code&gt; div&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If there are no more tasks inside the div i.e. the are no more tasks left to show, we need to add a message to let the user know&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code, we would have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Step 1&lt;/span&gt;
    &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Step 2&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There are no tasks to be shown.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Optional Step 3: Console log for debugging purposes&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Task with id &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deleted successfully.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Last but not least, let's put the actual delete &lt;code&gt;button&lt;/code&gt; element inside the &lt;code&gt;message&lt;/code&gt; component in the &lt;code&gt;showTasks&lt;/code&gt; function, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="c1"&gt;// Creating the delete button element&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;deleteButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;deleteButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aria-label&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;deleteButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Adding it to the div message header&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextSibling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ..&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And... we are done 👏! Now let's test it out, start your local development server and go the &lt;code&gt;index&lt;/code&gt; page of our application. If there are no tasks there, create some and when they render on the page you will see that a little &lt;code&gt;X&lt;/code&gt; button appears on top on the task description, like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LpEAPfxz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wxlboonrk2u4pxkledij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LpEAPfxz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wxlboonrk2u4pxkledij.png" alt="Screenshot Tasks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything went right, when you click on the &lt;code&gt;X&lt;/code&gt; button, the task should disappear. We can confirm this by looking up in the console:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--327TeUCA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/amenzlq0kjej5kb1lo9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--327TeUCA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/amenzlq0kjej5kb1lo9x.png" alt="Screenshot Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome 🎉! Everything works as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  🕵️‍♂️ Let's Recap
&lt;/h2&gt;

&lt;p&gt;Whew! What a journey, we sure learned a lot since part one, so let's do a quick review of all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We learned what &lt;code&gt;IndexedDB&lt;/code&gt; API is and how we can create our own database in the browser&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We learned how to perform &lt;code&gt;CRUD&lt;/code&gt; operations using &lt;code&gt;transactions&lt;/code&gt; and &lt;code&gt;request&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We learned how we can create a &lt;code&gt;Database&lt;/code&gt; class with custom methods that let us seamlessly use the ones exposed by the &lt;strong&gt;API&lt;/strong&gt;, effectively enclosing the business logic we could need&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And finally, we learned how we can use the &lt;code&gt;Database&lt;/code&gt; class in a real-world project by creating our own to-do application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete code of the project can be found at &lt;strong&gt;GitHub&lt;/strong&gt; on the &lt;code&gt;master&lt;/code&gt; branch. The specific changes we made for this part are under the commit tagged as &lt;code&gt;finished-code-part-three&lt;/code&gt;. I invite you to fork the project so you can experiment with it.&lt;/p&gt;

&lt;p&gt;Also, the project is up and running on &lt;strong&gt;Netlify&lt;/strong&gt; at the following URL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://indexed-todo-app.netlify.app/"&gt;https://indexed-todo-app.netlify.app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you so much for reading, I hope all of this is useful to you if you have comments, questions or suggestions please leave them down below.&lt;/p&gt;

&lt;p&gt;See you next time 👋.&lt;/p&gt;




&lt;p&gt;&lt;small&gt;1: This is relevant because the project uses &lt;b&gt;Bulma&lt;/b&gt; as a CSS framework but it does &lt;i&gt;&lt;b&gt;not&lt;/b&gt;&lt;/i&gt; mean you can't call the function in another way. What's important is that the element that calls the function is inside the article block, otherwise, you won't have access to its &lt;code&gt;id&lt;/code&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>JavaScript: Building a To-Do App (Part 3)</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Fri, 24 Jul 2020 18:54:03 +0000</pubDate>
      <link>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-3-55ni</link>
      <guid>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-3-55ni</guid>
      <description>&lt;h2&gt;
  
  
  📖 Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to part three of the "Introduction to the IndexedDB API" series. In the last post, we started the construction of our application by creating a &lt;code&gt;Database&lt;/code&gt; class that contains the instance of the indexed database and we also managed to save some data by creating a &lt;code&gt;persist&lt;/code&gt; method. In this part, we are going to focus on how to retrieve the data stored in the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a method on the &lt;code&gt;Database&lt;/code&gt; class called &lt;code&gt;getOpenCursor&lt;/code&gt; that returns the &lt;code&gt;cursor&lt;/code&gt; from the &lt;code&gt;objectStore&lt;/code&gt; (if you don't know what a &lt;code&gt;cursor&lt;/code&gt; is, or need a little refresher, refer back to part one 😉)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete the &lt;code&gt;showTasks&lt;/code&gt; function on the &lt;code&gt;index.js&lt;/code&gt; file (present on the starting code) so that it renders out the tasks in the page&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Initial Setup
&lt;/h3&gt;

&lt;p&gt;If you want to code along (which is &lt;strong&gt;&lt;em&gt;highly recommended&lt;/em&gt;&lt;/strong&gt;), then go to the following GitHub repository:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101" rel="noopener noreferrer"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/js-todo-app-indexed_db" rel="noopener noreferrer"&gt;
        js-todo-app-indexed_db
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a to-do web application that uses the IndexedDB API.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Once there, go to the &lt;code&gt;README.md&lt;/code&gt; file and search for the link labeled &lt;code&gt;Starting Code&lt;/code&gt; for the second part. It will redirect you to a commit tagged as &lt;code&gt;starting-code-part-two&lt;/code&gt; that contains all we have done so far plus the new &lt;code&gt;showTasks&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the &lt;code&gt;getOpenCursor&lt;/code&gt; Function 🛠
&lt;/h2&gt;

&lt;p&gt;Once we have downloaded the source code, let's go to the &lt;code&gt;Database&lt;/code&gt; class and create a method called &lt;code&gt;getOpenCursor&lt;/code&gt;, inside, similar to the &lt;code&gt;persist&lt;/code&gt; function, we are going to get an instance of the object store and use the &lt;code&gt;openCursor()&lt;/code&gt; method to send a &lt;em&gt;request&lt;/em&gt; for the cursor to open. The key difference here, in contrast to the &lt;code&gt;persist&lt;/code&gt; function, is that we are going to return the request so it becomes easier to handle the &lt;code&gt;onsuccess&lt;/code&gt; callback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readonly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;onsuccess&lt;/code&gt; callback is special because it will be emitted for every&lt;sup&gt;1&lt;/sup&gt; record on the table but only if we explicitly tell it to do so by calling the &lt;code&gt;continue()&lt;/code&gt; method.&lt;br&gt;
The resultant code in the &lt;code&gt;showTasks&lt;/code&gt; function would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Leave the div empty&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Advance to the next record&lt;/span&gt;
      &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// There is no data or we have come to the end of the table&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, &lt;em&gt;if&lt;/em&gt; the cursor is not &lt;code&gt;undefined&lt;/code&gt; then the data exist and is stored within the &lt;code&gt;value&lt;/code&gt; property of the &lt;code&gt;cursor&lt;/code&gt; object, that means we can recover the information as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Advance to the next record&lt;/span&gt;
      &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// There is no data or we have come to the end of the table&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great 👏! To display this information on the page, we'll be using &lt;strong&gt;Bulma's&lt;/strong&gt; &lt;code&gt;message&lt;/code&gt; component.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, let's create an &lt;code&gt;article&lt;/code&gt; element with the class of &lt;code&gt;message&lt;/code&gt; and &lt;code&gt;is-primary&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Using the InnerHTML property, we are going to create two &lt;code&gt;divs&lt;/code&gt;, one for the title and one for the description&lt;/li&gt;
&lt;li&gt;Append the new task to the &lt;code&gt;taskContainer&lt;/code&gt; div&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to visit &lt;strong&gt;Bulma's&lt;/strong&gt; official documentation &lt;a href="https://bulma.io/documentation/components/message/" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want to know a little more.&lt;/p&gt;

&lt;p&gt;The resulting code would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Step 1&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Step 2&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;div class="message-header"&amp;gt;
          &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="message-body"&amp;gt;
          &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
      `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="c1"&gt;// Step 3&lt;/span&gt;
       &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="c1"&gt;// Step 4&lt;/span&gt;
       &lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// There is no data or we have come to the end of the table&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good 👏! Now, what should happen if the cursor is &lt;code&gt;undefined&lt;/code&gt;? We need to consider two edge cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There were at least one record saved and now the cursor has reached the end of the table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The table was empty&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An easy way to know if the table is indeed empty is by checking if the &lt;code&gt;taskContainer&lt;/code&gt; div is empty (that is, it has no children), in that case, we can simply create a &lt;code&gt;paragraph&lt;/code&gt; element with the text "There are no tasks to be shown." to let the user know that there are no tasks created yet, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There are no tasks to be shown.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;tasksContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Our &lt;code&gt;showTasks&lt;/code&gt; function is complete. Now we have to figure out &lt;em&gt;where&lt;/em&gt; we should call it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using the &lt;code&gt;showTasks&lt;/code&gt; Function 👨‍💻
&lt;/h2&gt;

&lt;p&gt;Remember the &lt;code&gt;oncomplete&lt;/code&gt; event of the &lt;code&gt;transaction&lt;/code&gt; object in the &lt;code&gt;saveTasks&lt;/code&gt; function? We said that if the event is emitted, we could assure the task was created, what better place to call our &lt;code&gt;showTasks&lt;/code&gt; function than within this callback? That way we can update the list of created tasks on the page every time a new one is saved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oncomplete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task added successfully!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's test it out! Start your local development server, go to the &lt;code&gt;index&lt;/code&gt; page of the application, and create a new task:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fanzda3coqc20mej47on8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fanzda3coqc20mej47on8.png" alt="Index Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Immediately after you press on the &lt;code&gt;Create&lt;/code&gt; button, you will see a new panel appears at the bottom, effectively replacing the "There are no tasks to be shown" message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdpc9jpo8caa7oqv4sw4e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdpc9jpo8caa7oqv4sw4e.png" alt="Screenshot Panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome 🎉! Everything works as expected! But... what's this? When you reload the page, the panel disappears and the text saying that there are no tasks returns once again but, we know this is not true, in fact, if we check the &lt;em&gt;Application&lt;/em&gt; tab in the &lt;strong&gt;Chrome DevTools&lt;/strong&gt; we will see our task there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjn1wnw6ypkw66ll5c094.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjn1wnw6ypkw66ll5c094.png" alt="Application Tab Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what's wrong? Well, &lt;em&gt;nothing&lt;/em&gt;. The problem is that we are &lt;em&gt;only&lt;/em&gt; calling the &lt;code&gt;showTasks&lt;/code&gt; function when we add a new task but we also have to call it when the page is loaded because we don't know if the user has already created some [tasks]. We &lt;em&gt;could&lt;/em&gt; just call the function inside the listener of the &lt;code&gt;DOMContentLoaded&lt;/code&gt; event but is better to play it safe and call the function inside the &lt;code&gt;onsuccess&lt;/code&gt; event emitted when the connection with the database is established.&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;could&lt;/em&gt; pass a callback function to the constructor but, is better if we do a little refactoring here because the constructor is not supposed to take care of that. Let's create a new function called &lt;code&gt;init()&lt;/code&gt;, inside let's move out the code where we handle the &lt;code&gt;onsuccess&lt;/code&gt; and the &lt;code&gt;onupgradeneeded&lt;/code&gt; events. Of course, the function will receive two arguments, the fields of the table and the callback function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Database &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: created successfully`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;successCallback&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;successCallback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;autoIncrement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getOpenCursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in the &lt;code&gt;index.js&lt;/code&gt; file, we create the instance of the &lt;code&gt;Database&lt;/code&gt; class and call the &lt;code&gt;init()&lt;/code&gt; method right after, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DBTasks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title, description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;em&gt;voilá&lt;/em&gt;! No matter how many times we refresh the page, if there any tasks saved in the database, the app will render them right away. &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Recap 🕵️‍♂️
&lt;/h2&gt;

&lt;p&gt;In this third part, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learned how to use the &lt;code&gt;IDBCursorWithValue&lt;/code&gt; interface&lt;/li&gt;
&lt;li&gt;Learned how to properly retrieve the information saved in the database through the &lt;code&gt;cursor&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;Learned how to render the data on the page&lt;/li&gt;
&lt;li&gt;Organized the responsibilities in the &lt;code&gt;Database&lt;/code&gt; class by creating a new function &lt;code&gt;init()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, the complete code for this section is available in the project's repository under the tag &lt;code&gt;finished-code-part-two&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's all 👏! In the next part, we will finish the application by adding the ability to effectively delete any given task from the database.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading! If you have questions or suggestions please leave them down below. See you next time 👋.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>JavaScript: Building a To-Do App (Part 2)</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Sun, 19 Jul 2020 21:14:46 +0000</pubDate>
      <link>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-2-1lh9</link>
      <guid>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-2-1lh9</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Welcome to part two of the Introduction to the IndexedDB API series, last time we learned about the basics of the API and how we could perform some of the most common operations. In this part, we will begin the construction of our To-Do web application by applying that knowledge. Specifically, we will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get familiar with the boilerplate code of the application&lt;/li&gt;
&lt;li&gt;Create a class that encapsulates the IndexedDB instance&lt;/li&gt;
&lt;li&gt;Set the logic to create and save a new task&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;To start, make sure you have a recent version of &lt;strong&gt;NPM&lt;/strong&gt;, then go to the following &lt;strong&gt;GitHub&lt;/strong&gt; repo &lt;a href="https://github.com/DevTony101/js-todo-app-indexed_db"&gt;here&lt;/a&gt; and, in the &lt;code&gt;README&lt;/code&gt;, find the &lt;code&gt;Want to Code Along?&lt;/code&gt; section and download the code tagged as &lt;code&gt;starting code&lt;/code&gt; for part one.  The project uses webpack and webpack-dev-server to create a local development server as well as &lt;strong&gt;Bulma&lt;/strong&gt; (a modern CSS framework) for the front-end. Once you got it, execute the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
npm run start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The first one will download all the dependencies, the second one will run the &lt;em&gt;start&lt;/em&gt; script defined in the &lt;code&gt;package.json&lt;/code&gt; file and start the local server. If everything goes well, the server will start listening in the &lt;code&gt;port 8080&lt;/code&gt; at the following URL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://localhost:8080/dist/"&gt;http://localhost:8080/dist/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Project Structure
&lt;/h4&gt;

&lt;p&gt;Letting the &lt;code&gt;node_modules/&lt;/code&gt; folder aside, the project has the following file structure:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;│   .babelrc
│   .gitignore
│   package-lock.json
│   package.json
│   webpack.config.js
│
├───dist
│   │   index.html
│   │   main.js
│   │
│   └───assets
│       └───css
│               index.css
│
└───src
    │   index.js
    │
    └───database
            database.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;dist/&lt;/code&gt; folder contains the public files. We won't necessary edit these files but I encourage you to personalize the &lt;code&gt;index.html&lt;/code&gt; file and create your layout&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;src/&lt;/code&gt; folder contains the &lt;strong&gt;javascript&lt;/strong&gt; code, including the &lt;code&gt;index.js&lt;/code&gt; file (the entry point of our application) and the &lt;code&gt;database.js&lt;/code&gt; file that will export the &lt;code&gt;Database&lt;/code&gt; class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The rest of the files are configuration files and should not be changed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Note: It is not necessary to run the start script every time we make a change as the webpack-dev-server dependency will automatically compile the code and reload the page.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;index.js&lt;/code&gt; file already has a &lt;code&gt;saveTask&lt;/code&gt; function that will be called when a &lt;code&gt;submit&lt;/code&gt; event on the form is fired.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating the Database
&lt;/h3&gt;

&lt;p&gt;As said earlier, the &lt;code&gt;database.js&lt;/code&gt; file contains a class. This class will encapsulate the IndexedDB instance and manage the methods for the CRUD operations. Let's start by creating the instance, remember that we need two things, the &lt;strong&gt;name&lt;/strong&gt; and the &lt;strong&gt;version&lt;/strong&gt; of the database, we can easily pass these information as variables to the constructor, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Database &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: created successfully`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, back in the &lt;code&gt;index.js&lt;/code&gt; file, let's create a new instance of our &lt;code&gt;Database&lt;/code&gt; class by passing in the name and version we want, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cBTrWKeo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1v6a30in2ra8ddrihdjo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cBTrWKeo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1v6a30in2ra8ddrihdjo.png" alt="Screenshot IndexJS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if we run the &lt;code&gt;start&lt;/code&gt; script once again (remember, it's not necessary if it was already running) we will see the message &lt;code&gt;Database DBTasks: created successfully&lt;/code&gt; but, if we &lt;em&gt;really&lt;/em&gt; want to make sure our database was created, we can go to the &lt;strong&gt;Application&lt;/strong&gt; tab on the Chrome DevTools and check under &lt;code&gt;Storage &amp;gt; IndexedDB&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M2ne2OnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1s0th8k7d34o2bo5k0ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M2ne2OnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1s0th8k7d34o2bo5k0ny.png" alt="Screenshot Application Tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the database indeed exists but is empty.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating the &lt;code&gt;persist&lt;/code&gt; Function
&lt;/h3&gt;

&lt;p&gt;Before we can attempt to save something remember, we first need to create the schema. We &lt;em&gt;could&lt;/em&gt; create the fields directly in the constructor, but we want the &lt;code&gt;Database&lt;/code&gt; class to be capable of building different databases with different fields. For that purpose, let's pass another variable to the constructor called &lt;code&gt;fields&lt;/code&gt; that can be either a string or an array and create the model from it, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;autoIncrement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now we can easily pass the various fields we could need for our database. The following code snippets are equivalent:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DBTasks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title, description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DBTasks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now when the database is created, it will have an object store attached to it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_WDN_rWt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l7n7bi7573a9py2plk2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_WDN_rWt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l7n7bi7573a9py2plk2t.png" alt="Screenshot Application Tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bravo 🎉🎉 !! Our database is up and running, now the only thing left to do is to create a new class method that receives an object (a task) and save it. Let's go to our Database class and create a method called persist, next let's create an IDBTransaction object from the instance of the database and then get access to the object store, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An object was expected.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, in the previous part, we also talked about a &lt;code&gt;request&lt;/code&gt; that we have to make through the &lt;code&gt;objectStore&lt;/code&gt; object, that's because, to save a new record, we need to call the &lt;code&gt;add()&lt;/code&gt; method on the &lt;code&gt;objectStore&lt;/code&gt; object, said method will return an &lt;code&gt;IDBRequest&lt;/code&gt; object with information about the status of our petition. This is useful because we can then pass a callback function to execute when the request is complete. The whole process would look something like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An object was expected.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Great 👏! We are almost done as we still need to supply a callback for when the transaction is complete, we &lt;em&gt;could&lt;/em&gt; pass more callbacks to the &lt;code&gt;persist&lt;/code&gt; function, but it is more practical if we just return the &lt;code&gt;transaction&lt;/code&gt; object, that way we can handle it in the &lt;code&gt;index.js&lt;/code&gt; file.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using the &lt;code&gt;persist&lt;/code&gt; Function
&lt;/h3&gt;

&lt;p&gt;Before moving out to the &lt;code&gt;index.js&lt;/code&gt; file, let's think for a moment what kind of operations we could execute as callbacks for the request and the transaction. &lt;/p&gt;

&lt;p&gt;If a request is &lt;em&gt;fulfilled&lt;/em&gt;, it does not necessarily mean that everything went fine, it just tells us that our request was accepted, therefore, we can not assure that the object was successfully saved but, we sure can say that the data recollected from the &lt;code&gt;form&lt;/code&gt; were stored in the &lt;code&gt;task&lt;/code&gt; object and if that's the case, we can then reset the form.&lt;/p&gt;

&lt;p&gt;On the other hand, if a transaction is completed successfully, then there were no errors during the process that was requested and if that's the case, then we can be sure the object was successfully saved.&lt;/p&gt;

&lt;p&gt;Now that we have that figured out, we can code it! The implementation would look something like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;saveTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oncomplete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task added successfully!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now to the fun part, let's test it! Go to your browser and create a task you would like to do, in my case, I want to finish all my series on Netflix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p6-dltvK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9puu3p0622cg850f3j1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p6-dltvK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9puu3p0622cg850f3j1d.png" alt="Screenshot Test Application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press on the &lt;code&gt;Create&lt;/code&gt; button and you will see that the &lt;code&gt;form&lt;/code&gt; resets itself (as intended), and after a few seconds (or less) you should see the following message on your console:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k3MgWd9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5w9qtr2przlmhet1nb9s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k3MgWd9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5w9qtr2przlmhet1nb9s.png" alt="Screenshot Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we check again the &lt;strong&gt;Application&lt;/strong&gt; tab, we now will see our newly saved data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c8ET0YBZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xupmis5icyqjld4vhhee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c8ET0YBZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xupmis5icyqjld4vhhee.png" alt="Screenshot Application Tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent! The task has been successfully saved.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let's Recap
&lt;/h3&gt;

&lt;p&gt;In this second part, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created the &lt;code&gt;Database&lt;/code&gt; class to encapsulate the IndexedDB instance&lt;/li&gt;
&lt;li&gt;Learned how we can create fields dynamically in the constructor of the &lt;code&gt;Database&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;Learned how we can see the status of our database by checking in the &lt;strong&gt;Application&lt;/strong&gt; tab on the Chrome DevTools&lt;/li&gt;
&lt;li&gt;Learned how we can save new objects by using the &lt;code&gt;add()&lt;/code&gt; method on the &lt;code&gt;objectStore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Learned what to expect when the &lt;code&gt;request&lt;/code&gt; emits the &lt;code&gt;onsuccess&lt;/code&gt; event&lt;/li&gt;
&lt;li&gt;Learned what to expect when the &lt;code&gt;transaction&lt;/code&gt;  emits the &lt;code&gt;oncomplete&lt;/code&gt; event&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete code is available in the project repo tagged as &lt;code&gt;finished code&lt;/code&gt; for part one, go check it out.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevTony101"&gt;
        DevTony101
      &lt;/a&gt; / &lt;a href="https://github.com/DevTony101/js-todo-app-indexed_db"&gt;
        js-todo-app-indexed_db
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a to-do web application that uses the IndexedDB API.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;That's all! In the next part, we will begin with the implementation of a function that allows us to retrieve the objects stored in the database and then display them on the page.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading! If you have questions or suggestions please leave them down below. See you next time 👋.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>JavaScript: Building a To-Do App (Part 1)</title>
      <dc:creator>Miguel Manjarres</dc:creator>
      <pubDate>Thu, 16 Jul 2020 20:29:49 +0000</pubDate>
      <link>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-1-4382</link>
      <guid>https://dev.to/devtony101/javascript-building-a-to-do-app-with-the-indexeddb-api-part-1-4382</guid>
      <description>&lt;p&gt;If you have already developed dynamic web applications, you are probably familiar with the concepts of &lt;code&gt;window.localStorage&lt;/code&gt; and &lt;code&gt;window.sessionStorage&lt;/code&gt;, they are great tools that let us save information directly into the browser, but there is a problem, you can only save data in the form of a string, sure, there are some workarounds to this, like using the &lt;code&gt;JSON.stringify()&lt;/code&gt; method but, wouldn't it be nice if we could just save the data as an object and retrieve it the same way?&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;This is part one of a four part series where we will build a (yet another) To-Do web application using the &lt;strong&gt;IndexedDB API&lt;/strong&gt;. In this first part however we fill focus on the theory. Specifically we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have a brief introduction about what the IndexedDB API is &lt;/li&gt;
&lt;li&gt;See how can we get an instance of a newly created database&lt;/li&gt;
&lt;li&gt;Learn about the most relevant objects and functions to perform the &lt;strong&gt;CRUD&lt;/strong&gt; operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is the IndexedDB API?
&lt;/h3&gt;

&lt;p&gt;IndexedDB is a low level API that let us save structured-like data, like files and binary-large-objects (blobs). It provides us with methods for both synchronous and asynchronous operations, the latter being the one that web browsers implement.&lt;/p&gt;

&lt;p&gt;In order create a brand new database we need to use the &lt;code&gt;open(name, version)&lt;/code&gt; method on the &lt;code&gt;indexedDB&lt;/code&gt; property of the &lt;code&gt;window&lt;/code&gt; object. The &lt;code&gt;open()&lt;/code&gt; method receives two parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: The name of the database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;version&lt;/strong&gt;: The version to open the database with. It defaults to &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This returns a &lt;code&gt;IDBOpenDBRequest&lt;/code&gt; object on which we can supply a callback for when the request is successfully resolved, and if that's the case, we can store the reference to our database.&lt;/p&gt;

&lt;p&gt;The whole process looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbVersion&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbVersion&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;dbRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dbRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Database created successfully!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// You can also supply a callback for when (and if) something goes wrong&lt;/span&gt;
&lt;span class="nx"&gt;dbRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something went wrong...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great 👏! We now have access to a brand new database, but right now its &lt;em&gt;empty&lt;/em&gt; with no model whatsoever, before we can attempt to save something we need to specify a &lt;em&gt;schema&lt;/em&gt; and for that we need to create an &lt;code&gt;IDBObjectStore&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to IDBOjectStore
&lt;/h3&gt;

&lt;p&gt;According to the official documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is an interface of the IndexedDB API and represents an object store in a database&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of it as the model in a &lt;strong&gt;Relational DataBase&lt;/strong&gt;, with a major exception, there is no &lt;em&gt;id&lt;/em&gt; field. Whenever we want to save a new record, a &lt;em&gt;key&lt;/em&gt; must be provided, then the object store will use this &lt;em&gt;key&lt;/em&gt; to access the object (like indexes in an array) but, if we truly want to mimic the behavior of a real &lt;strong&gt;RDB&lt;/strong&gt;, we can tell the object store to automatically generate this value for every new object we save by passing an optional &lt;code&gt;optionalParameters&lt;/code&gt; object when we first create the object store.&lt;/p&gt;

&lt;p&gt;When the object store is successfully created, we can use the instance to create the fields of our model using the &lt;code&gt;createIndex(name, keyPath, parameters)&lt;/code&gt; method, each parameter being:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: The name of the field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;keyPath&lt;/strong&gt;: The keyPath (name of the &lt;em&gt;key&lt;/em&gt; field)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parameters&lt;/strong&gt;: An optional object where we can specify additional properties to our field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Beware: You can only perform changes on the schema in the context of a &lt;code&gt;versionChange&lt;/code&gt; transaction. More on transactions later.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When we first open up a request to create a database, we assign a &lt;em&gt;version&lt;/em&gt; to it, and because that database didn't exist before, it &lt;em&gt;upgraded&lt;/em&gt; its version from 0&lt;sup&gt;1&lt;/sup&gt; to whatever number we pass (&lt;code&gt;1&lt;/code&gt; being the default), a &lt;code&gt;onupgradeneeded&lt;/code&gt; event is fired&lt;sup&gt;2&lt;/sup&gt; and most importantly, a &lt;code&gt;versionChange&lt;/code&gt; transaction is created.&lt;/p&gt;

&lt;p&gt;The code to create the object store, given an &lt;code&gt;IDBOpenRequest&lt;/code&gt; object is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;dbRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// We retrieve the instance of the database&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Assign a key field to every record&lt;/span&gt;
    &lt;span class="na"&gt;autoIncrement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// The key is given by a key generator in a ordered sequence&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// We then create the fields&lt;/span&gt;
  &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wonderful 👏! We now have our database populated with fields (columns), but how do we save (or update, or delete) any record on it?&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to IDBTransaction
&lt;/h3&gt;

&lt;p&gt;According to the official documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is an interface of the IndexedDB API. It provides a static, asynchronous transaction on a database using event handler attributes. All reading and writing of data is done within transactions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think no further explanation is needed. To start (and use) a transaction we can follow this five steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a transaction through the &lt;code&gt;transaction()&lt;/code&gt; method on our database&lt;/li&gt;
&lt;li&gt;Set the mode of the transaction to either &lt;code&gt;readonly&lt;/code&gt; or &lt;code&gt;readwrite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Access the &lt;code&gt;IDBObjectStore&lt;/code&gt; through the transaction and store it&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;IDBObjectStore&lt;/code&gt; to make an asynchronous request (to delete or create something, for example)&lt;/li&gt;
&lt;li&gt;Define a behaviour for when the request is fulfilled&lt;/li&gt;
&lt;li&gt;Define a behaviour for when the transaction is completed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code, it would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// readonly or readwrite&lt;/span&gt;
&lt;span class="c1"&gt;// Step 1-2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Step 3&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Step 4&lt;/span&gt;
&lt;span class="c1"&gt;// We open up the request through the objectStore object, we will see more on this in the next part&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Step 5&lt;/span&gt;
&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Step 6&lt;/span&gt;
&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Operation was successful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Excellent 👏! Up to this point, we can do pretty much anything we want with our data, but we have yet to see how can we actually retrieve the information and use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to IDBCursorWithValue
&lt;/h3&gt;

&lt;p&gt;According to the official documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is an interface of the IndexedDB API. It represents a cursor for traversing or iterating over multiple records in a database&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of it as a literal cursor that can go in any direction (up and down) across the records.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7cerM-Dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qymnv2h5qso5c97wsj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7cerM-Dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qymnv2h5qso5c97wsj4.png" alt="table_cursor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get an instance of a cursor, we can follow this steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grab the &lt;code&gt;objectStore&lt;/code&gt; instance from the database&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;openCursor()&lt;/code&gt; on the &lt;code&gt;objectStore&lt;/code&gt;, it will perform a &lt;code&gt;request&lt;/code&gt; and return a new &lt;code&gt;IDBCursorWithValue&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;Define a behaviour for when the request is fulfilled successfully&lt;/li&gt;
&lt;li&gt;Get the cursor from the event passed to this callback, if it's &lt;code&gt;undefined&lt;/code&gt; then there is no data to retrieve&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Steps 1-2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Step 3&lt;/span&gt;
&lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openCursor&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 4&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// There is at least one record&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// There is no data or is the end of the table&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;onsuccess&lt;/code&gt; callback will be fired up for every record on the table.&lt;/p&gt;

&lt;p&gt;That's it! Now we have everything we need to start developing our application, we will begin right away in the next chapter.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading! If you have questions or suggestions please leave them down below. See you next time 👋.&lt;/p&gt;




&lt;p&gt;&lt;small&gt;1: This is not accurate, but rather an example to make it easier to understand why the &lt;code&gt;onupgradeneeded&lt;/code&gt; event is fired up&lt;/small&gt;&lt;br&gt;
&lt;small&gt;2: The &lt;code&gt;onupgradeneeded&lt;/code&gt; event is fired up whenever an attempt to open a database with a version higher than its current version is made and not only when the database it's first created&lt;/small&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>database</category>
    </item>
  </channel>
</rss>
