69. Logging out via the UI

In this video, we're going to create a UI feature to allow a user to log out. So you'll see in the nav bar here we have a "sign in or register" link. So our strategy will be to change that to a "logout link" conditional on the user being logged in.

Coming over to the relevant component, which is the StickNav, let's being by putting a div above the login link div. We'll add a v-if to this one, and we'll call the check method of the Vue Auth API.

If we don't pass any arguments to check, it will simply check if the user is authenticated or not.

Don't forgot to also add a v-else to the sibling div.

Inside the first div, let's first display the authenticated user's name. We'll put "Hi" followed by a text interpolation. Inside this, we'll put $auth.user to retrieve the user object, and then specify the name property.

client/components/StickyNav.vue

<div v-if="$auth.check()">
  Hi {{ $auth.user().name }}!
</div>
<div v-else>
  ...
</div>

In the browser, now, if you're logged in, you should see the user's name in the nav bar and the "sign in or register" link should be now hidden.

Next, we're going to add a logout link. To do this, put an anchor tag next to the interpolation. We'll give it an id of logout, and a blank href value.

Next, we'll add some classes, "blue-grey--text text--darken-4". These are simply Vuetify classes used for styling.

Finally, let's add an event handler by going @click.prevent="logOut". This will allow us to hijack the click event of this anchor.

client/components/StickyNav.vue

<div v-if="$auth.check()">
  Hi {{ $auth.user().name }}! <a
    id="logout"
    href=""
    class="blue-grey--text text--darken-4"
    @click.prevent="logOut"
  >Logout</a>
</div>

Logout function

Vue Auth has an inbuilt logout function, of course, so we just need to configure it correctly before we use it.

Let's add a new property to our config, logoutData. We'll assign this an object and give it a property url, which will be "/users/logout", and for this one we'll also need to set the method to "GET" as the default for Vue Auth is the POST verb here for some reason.

Let's also add a redirect property and set that to the home page again by assigning { name: ROUTE_NAME_HOME }. We're also going to add another property makeRequest and set that to true. This is used to ensure an API request is made, as the default behaviour is simply to delete the token locally.

client/auth.js

logoutData: {
  url: "/users/logout",
  method: "GET",
  redirect: { name: ROUTE_NAME_HOME },
  makeRequest: true
},

logOut method

Okay, now that we're displaying the log out link and our logout method is configured correctly, let's define the click handling method in StickyNav.

The first thing we'll do is empty the shopping cart since we don't want any cart items to persist once the user is logged out.

To do this, we're first going to import the Item model into this component.

We'll then add a methods property to our config, and add a property logOut.

To empty the cart, let's set the value of cart to 0 on every Item model instance. So we'll use the Item model and call the the update method, passing in an object.

We'll now add a where clause, and we'll assign a function that simply returns true. The idea here is that we want to update every record!

We can then set a data property and define the data we want to update. Let's set cart to 0.

With that done, let's now call this.$auth.logout() to complete the function.

client/components/StickyNav.vue

import Item from "@/store/models/Item";

export default {
  methods: {
    logOut () {
      Item.update({
        where: () => true,
        data: { cart: 0 }
      });
      this.$auth.logout();
    }
  }
};

Test

Let's test our logout function now by ensuring we've got some items in the cart, then clicking the logout link. You'll notice the UI update and shows the "sign in or register" link in the nav bar, and the cart is now empty.

Looking in Vue devtools, note the successful GET request to /users/logout. Also, the token has now been deleted from local storage.

Discussion

0 comments