Cool progress bars for Vue.js apps
Using NProgress, Axios and Vue Router’s Global Guards
Problem
Isn’t it frustrating when you click on a link and nothing seems to happen? The Internet isn’t always fast as you expected, therefore we need to let our users know the data is on the way, and have something happen when they click a link that requires an API call which is why it’s important to design user-friendly applications that give feedback when parts of your webpage are still loading.
Solution
Route change
There are many ways to implement a progress bar in a JavaScript application and especially a Vue.js app, and we’re going to implement a solution of a progress bar with using global and per-route guards in Vue Router configuration. We’re going to use NProgress as a progress bar library.
First of all, install it from the command line
// with npm
npm install nprogress// or with yarn
yarn add nprogress
And then add the NProgress stylesheet as an extra import statement to our main.js.
import 'nprogress/nprogress.css'
Let’s consider we have our vue-router
configured and it means we have a file called router.js
Then we’ll use Global Route Guards inside our router.js and make the progress bar appear on every page of our app.
We need a way to not load the component onto the page until it’s done loading, and finish the progress bar after it. Because of that, we create a route instance and pass theroutes
option and calling two global route guards which start beforeEach
and stopafterEach
our progress bar on the route.
We also use route guard beforeEnter
inside our router and then dispatch
our action and only will we allow the navigation to continue by calling next()
In order for
then()
to get called when the API is returned we need to make sure this action returns a promise
In case you’re wondering what order all these hooks get called, it looks like this:
- Navigation triggered.
- Call global
beforeEach
guards. - Call
beforeEnter
in route configs. - Call global
afterEach
hooks.
Well, what about API calls?
Sometimes calling an API would necessitate without any change in URL. It means Vue
route guards will not work here, and no more calls to beforeEnter
or beforeEach
will be made. In this case, you will need to deal with your HTTP client. If you are using Axios, it allows you to intercept your requests and responses by using interceptors
and add some functionalities, like starting and stopping a progress bar just like this:
Let’s assume all your API calls are inside the Services file. In this file, you should create a new instance of Axios with your custom config and handle intercept requests or responses when a request is made, or when a response is received.
But in real-life…
There are situations in real projects that can not be covered by the above solution completely. Like when you do multiple API calls at the same time, the code example above will break your progress bar when the second API is called.
Well, that’s what I am going to write about in the near future ☕