A year ago or so I dedicated myself to learning NodeJS with a focus on writing web applications with the Express/Mongo stack. I was writing a bill tracking application as part of the learning process and the result was node-billz. Things were working well but a buddy introduced me to a new javascript framework: VueJS.

And down the rabbit hole I went.

It started off innocently enough, I wanted to easily be able to page through multiple pages of payments. Using VueJS I was able to leverage my existing API to load all of a users payments and easily add paging.

Once the payment page was done I started looking for more and more ways to implement Vue in the project. Eventually the choice was clear to me.

It was time to rethink node-billz

I love node-billz. It literally taught me everything I knew about coding javascript. I was trying do more things with VueJS and it just seemed that trying rewrite individual pages using Express was slowing me down. I decided to move the front end code completely to VueJS and the NuxtJS framework.

Express is definitely still part of the picture since it still powers the API. The core code performing the weekly and monthly bill calculations was removed from Express and refactored as computed properties in VueJS. The code that handled storing and retrieving data now live on as REST endpoints.  No code went to waste.

Honestly it goes to show just how versatile javascript is as a language.

NuxtJS Framework

There are a few reasons why I decided to go with Nuxt.

Organizing your application easy and it handles all the vue-router related code for you. The trade off here is your application routes have to follow NuxtJS rules. If you want to get creative with your application routes you might have some trouble.

Also Nuxt has the Vuex state management plugin included. Vuex provides an easy way to share data between components similar to React's Redux. It is easy to add Vuex to a VueJS application but Nuxt already has it configured. Just add your implementation.

Nuxt makes it easy to switch layouts based on the component. It is trivial implementing the same in VueJS but Nuxt has it out of the box. You can also embed application logic in layouts. I have the default layout for authenticated users loading data into vuex where the layout for unauthenticated users does not. Components relying on vuex will not have to worry about verifying whether or not it has been initialized since the layout will have finished loading before any page level components are created. It might seem confusing, but once you understand the lifecycle of components it makes things easier to understand.

Finally, Nuxt will easily deploy from the command line with now-cli. This is like surge.sh but for NodeJS applications. Initially I thought the price of their lowest tier was a little high but they handle multiple instances in multiple regions of both my frontend server and the backend Express server. Plus, you can scale additional instances from the command line; it could not be any easier.

Vuetify

The world runs on Bootstrap. Heck, node-billz ran on Bootstrap. Early on in the redesign I went with Bulma just for a change. I was pretty far in to the rewrite when I found Vuetify. Once I did I scrapped the entire project and started from scratch again.

If you have not heard of Vuetify before, it is a material design framework that enables you to easily build Google-like applications. There is a bit of a learning curve but once you have the basics down it is easy to build a beautiful UI. Even I could do it.

Authentication

I leveraged Passport to handle user authentication originally in node-billz, I was using Express so it was simple to integrate. I have a buddy at Auth0 so I decided to give them a try and I glad I did. It was easy enough to implement in Nuxt, there is even an example repo that does a decent job of explaining how to get things configured. You may still use a lot of colorful adverbs.

The biggest hurdle I faced switching from Passport to Auth0 is the fact that I no longer owned the user data. I already had a years worth of data so I needed to find a way to associate an Auth0 user to existing data.

I was able to set a userid field inside of app_metadata Auth0 returns as part of the user object returned by the json web token. In the case of existing users I was able to manually set this value. A new user logging in to the application will have this value automatically generated using an Auth0 hooks if they are using the social login feature, otherwise I have a rule setup to generate this value if they sign in with an email and password.

It took a little longer than I anticipated getting everything set correctly but I finally nailed everything down. I am no longer maintaining any identifiable user data in my databases which is awesome.

Vuex

I have mentioned Vuex briefly but when it comes to sharing data between components it will be your best friend. Once a user is authenticated I poll the API for the user's payees, payments and user settings and store these values in vuex. Every component has access to the vuex store so after the initial load there are no additional API are required once the user is authenticated. The only time I dispatch a refresh is when something changes or is created/updated.

Below is an example of loading the Vuex store data on the authenticated user layout.

<script>
  import { mapGetters, mapState } from 'vuex'
  
  export default {
    async created () {
      if (this.isAuthenticated && !this.$store.state.payees.length) {
        if (this.loggedUser.exp < Date.now() / 1000) {
          unsetToken()
          logout()
          this.$router.push({ path: '/auth/sign-in' })
        }
        await this.$store.dispatch('refreshUserSettings')
        await this.$store.dispatch('refreshPayees')
        await this.$store.dispatch('refreshPayments')
        await this.$store.dispatch('setInitialized')
      }
  
    },
    // the rest of the application code  
  }
</script>

Using Vuex to manage the application state makes things work seamlessly.

Wrapping it all up

I would have to say it was an enjoyable experience getting this application up and running. It was not always easy but it was a good learning experience.

Currently the billtrackr code is not available but I may release it in the future, however the node-billz code is available.

https://billtrackr.com