Vue Final Project - Part 6 - Adding a '404' route

Add a file named NotFound.vue to the views folder and put this code in it:

<template>
    <h1>We're sorry</h1>
    <h3>We can't fine the page you're looking for!</h3>
</template>

Then, in the router file (router/index.js) add an import for the NoteFound component like so:

import NotFound from '../views/NotFound.vue'

Now we'll add these two objects to the routes array:

{ path:"/404", component: NotFound, name:"NotFound"},
{ path:"/:catchAll(.*)", redirect: "/404" }

The first route object uses the path /404 and will display the NotFound component. The second route is a 'catch all', which means that if a url path is requested that does not exist, it will redirect the request to the /404 path.

Run the app and try it out by enter a url that we do not have a route, such as http://localhost:8080/foo. You should see the NotFound component.

A BUG!

Note that if you navigate to http://localhost:8080/users/foo you won't be redirected to the 404 page. This is because we have a route defined for this path (/users/:id).

This is a tricky bug, and can occur in a few different scenarios. There are various ways that we could deal with this. But an easy one for now if to put some logic inside the mounted() method of the UserDetails component.

Add this IF statement to the mounted() method in UserDetails.vue (put it before the call to getAllRoles()):

if(isNaN(this.userId)){
    this.$router.push({name:"NotFound"})
}

Test out the app. If you test it well you'll find that you cannot navigate to the AddUser route. To see this problem, navigate to the UserList component and then click the Add New User button. So we have created another bug by fixing the first one!

In order to fix this, we need to update the above IF statement to look like this:

if(this.$route.name != "AddUser" && isNaN(this.userId)){
    this.$router.push({name:"NotFound"})
}

While we're at it, here's another issue... Try a path that uses a number, but an invalid user id, like /users/100. In this case we have a number, but the failure point will come when we make a request to the JSON server, which (most likely) does not have a user with the id of 100. This will actually trigger our errorHandler() function in api.js, which will console log the error message and then throw an error. But what we should do is redirect to our NotFound component.

To do this, we can add a catch() to the call to getUserById() in UserDetails.vue (we are making the call inside the mounted() method). Update the call to getUserId() so that it looks like this:

getUserById(this.userId)
    .then(user => this.user = user)
    .catch(err => this.$router.push({name:"NotFound"}));

If you look at the errorHandler() function in api.js you'll see that it throws an error. This is the error that we are 'catching' in UserDetails. This allows your components to deal with errors in different ways.

Reminder - For the final project, you will have to Bootstrap the NotFound component