Wednesday, December 25, 2019

Equivalent Experiences: What Are They?

If you spend enough time interacting with digital accessibility practitioners, you may encounter the phrase “equivalent experience.” This saying concisely sums up a lot of the philosophy behind accessibility work.
Our industry tends to place a lot of focus on how, often at the expense of why. For accessibility-related concerns, it is vital to learn about the history, and lived experiences of disabled people as a context for understanding the need for design and code created with access in mind.
This is the first of two articles on the topic of equivalency, and how it relates to digital accessibility. It will help us define what an equivalent experience is. Once we have a common understanding established, I’ll then discuss how to go about implementing equivalent experiences for common accessibility-related issues.

The State Of Things

The truth of the matter is that even though we live in a multi-device world full of smartphones, augmented reality, voice assistants, and IoT smart sensors, our default is still predominately:
  • Visual,
  • large screen,
  • fast connection,
  • powerful computer and display,
  • male,
  • white,
  • wealthy,
  • young,
  • Western,
  • technologically-literate,
  • and abled.
This is reflective of the biases that are inherent in how we design, develop and grow products.
The previous list may not be the most comfortable thing to read. If you haven’t closed the browser tab already, take a moment to consider your daily workflows, as well as who your coworkers are, and you’ll begin to understand what I’m getting at.
At its core, delivering an equivalent experience is ultimately about preserving intent — with the intent being the motivating force behind creating a website or web app and all the content and features it contains.
This translates to making the meaning behind every interaction, every component, every photo or illustration, every line of code being understandable by the widest range of people, regardless of their device or ability.


What Isn’t An Equivalent Experience?

Showing examples of what something is not can be a way to help define it. For equivalent experiences, an example would be a web app geared towards use by the general public not having a mobile breakpoint.


With this example, everyone using a device with a small display is forced to pinch, pan, and zoom to get what they need. Here, the burden is placed on anyone whose only crime was using a smartphone.
Most likely, whoever conceived of, designed, and developed this didn’t stop to think about circumstances other than their own. In this sort of (unfortunately still all too common) scenario, I all but guarantee that the web app looks great on the laptops or desktops of the designers and developers who made it.


People using a smartphone to access this website are victims of circumstance. The extra effort someone needs to do to get it to work indirectly communicates that they weren’t a priority, and therefore not valued. If you’ve used the web for any significant portion of time, I’m willing to bet this, or a similar experience has happened to you.
This example is also a hop, skip, and a jump away from another common, yet serious accessibility issue we often don’t consider: screen zooming:

Screen Zooming

Screen zooming is when someone is prevented from being able to zoom their displays and make text larger—many native mobile apps are guilty of this. When you disallow this sort of behavior, you’re telling prospective users that unless they have vision similar to you, you aren’t interested in them being able to use your app.
For this scenario, a gentle reminder that we will all get older, and with aging comes a whole host of vision-related concerns.

Accessible Experiences Aren’t Necessarily Equivalent Ones

This might be a little difficult of a concept to grasp at first. Let’s use this Rube Goldberg machine made by Joseph Herscher to pass the pepper to his dinner guest to compare.

To pass the pepper, the machine, sends it through an elaborate system of weights, counterweights, ramps, rolling objects, catapults, guillotines, burners, timers, carousels, etc. — all constructed from commonly found kitchen items. While this setup will technically ensure the pepper is passed, it is an annoying, overwrought, time-intensive process.
Many digital experiences are a lot like a Rube Goldberg machine when it comes to accessibility. Since accessibility issues are so prevalent, many forms of assistive technology provide a large suite of features to allow their user to work around common obstacles.
Unfortunately, discovering obstacles, and then figuring out and activating the appropriate combination of features to overcome them can take a disproportionate amount of time and effort.
To say it another way: A simple click on a button for an abled person may take far more time and effort for a disabled person, depending on how the button has been made.


Chilling Effects

Frustratingly, the extra time and effort a disabled person has to put into operating a technically accessible experience may feed back into their disability condition(s). For example, the presence of a motor control disability such as arthritis may make the overall experience even more taxing.
Cognitive accessibility concerns are also another important thing to consider. What may seem easy to understand or intuitive to use for one person may not be for another. This is especially prevalent in situations where there is:
Cognitive accessibility isn’t an abstract concern, either. Poor user interface design that ignores the circumstances of the end user and dumps too much cognitive load onto them can have very real, very serious consequences.

Compounding Effects

These factors are not mutually exclusive. Proponents of Spoon Theory know that inaccessible experiences conspire to sap a person’s mental and physical energy, leaving them exhausted and demotivated. Worse, these sorts of scenarios are often more than just a person perpetually operating at a diminished capacity.
Frustrating digital experiences can lead to a person abandoning them outright, internalizing the system’s fault as their own personal failure. This abandonment may also translate to a person’s willingness and ability to operate other digital interfaces. In other words: the more we turn people away, the more they’ll stop trying to show up.

Consistency

For some, assistive technology can mean specialized browser extensions. These micro-apps are used to enhance, augment, and customize a browsing experience to better suit someone’s needs.
Damien Senger, digital designer, uses a browser extension called Midnight Lizard to enforce a similar experience across multiple websites. This helps them “to focus on the content directly and to limit having too big differences between websites. It is also helping me to avoid too harsh color contrasts that are really uncomfortable.“
Damien also writes, “Often websites are really difficult to read for me because either of the lack of consistency in the layout, too narrow lines or just not enough balance between font size and line height. Related to that, color can create a lot of unhelpful distraction and I am struggling when too harsh contrast is nearby text.”
How To Maintain Equivalency
In addition, Damien also augments their browsing experience by using ad blocking technology “not only for ads but to block animations or content that are too distracting for my ADHD.”
It’s not too difficult to imagine why distracting and annoying your users is a bad idea. In the case of ads, the industry is unregulated, meaning that rules to prohibit ADHD, migraine, and/or seizure-triggering animations aren’t honored. Through this lens, an ad blocker is a form of consumer self-defense.

Kenny Hitt also chimes in about ads: “…regardless of the platform, the thing that annoys me most are websites with ads that essentially cause the site to constantly auto update. This prevents me as a screen reader user from reading the content of those websites.”
Again, a lack of regulation means the user must take measures into their own hands to keep the experience equivalent.

How To Maintain Equivalency

Opportunity

A lack of an equivalent experience translates directly to lost opportunity. Many individuals I spoke with mentioned that they’d abandon a digital experience that was inaccessible more often than not.
Brian Moore mentions, “there are web sites where I like their products a lot but won’t buy them because the site itself is such a struggle, and attempts to reach out have met with either silence or resistance to taking any action.”
Brian cites the Fluance website as the most recent example. The bugs present in its shopping user flows prevents him from buying high-end consumer audio equipment.
Fluance’s entire web presence exists to sell products. While updating a website or web app to be accessible can be an effort-intensive process, it would definitely be in Fluance’s best interest to make sure its checkout user flow is as robust as it could be.



Friday, November 15, 2019

How To Feel More Energized Even When You’re Stuck At A Desk All Day

A desk is an essential piece of equipment for a web designer. Without it, you’d end up working from wobbly tables at cafes or staring down at your lap all day — uncomfortable options, to say the least. Then again, your desk could also cause you discomfort if you sit in it the wrong way or for too long. Rather than feeling like your desk is a torture device, we shares some pointers for enjoying the time you spend there.


Let me tell you a little story.
I used to work for a n agency. It was my job to copy-and-paste translations from one document into another and then to review the writing for errors. I worked between 10 and 12 hours every day, usually taking lunch at my desk (if I remembered to do so) and physically repeated the same thing over and over: mousing back and forth between my two giant computer screens and staring at too-small type.
Two years later, I found myself in physical therapy because I’d worn away the tissue beneath my right shoulder cap and had developed tennis elbow. Despite the months of therapy to repair my arm, I primarily use my left arm to work today. And although it feels a heck of a lot better than trying to power through the pain that happens when working with my right…
It makes me much slower than I used to be
Which can lead to longer hours in front of the computer
And I experience higher levels of stress, frustration and fatigue as a result.
I feel like if you’ve had a desk job for long enough, you have a similar story to tell. Maybe yours isn’t due to bad posture or technique. Maybe it has to do with the fact that you forget to eat lunch most days and don’t remember what it’s like to be outside when the sun is at its brightest. Or you move from your desk to the couch to the bed and back again, never giving your body or mind the physical activity it needs to stay energized.
Rather than let this be our collective fate because of the nature of our work, let’s try and change the narrative. Today, we’re going to look at some things you can do to feel more alert and energized even if you’re stuck at your desk for most of the day.

Fix Your Desk Setup and Alignment

Even if it feels more comfortable to work from your couch or bed or to slouch down in your work chair, the long-term benefits of not sitting properly will haunt you. Trust me.
I don’t know how old most of you are, but you may or may not have had to go through typing classes in school as I did. We didn’t just learn to type in them. We learned the right posture for sitting before a computer.

Basically, you want to aim for the following:
  • Body folded at 90-degree angles,
  • Back straight against the chair,
  • Feet flat on the floor,
  • Arms bent at the elbows,
  • Fingers hover above the keyboard or mouse without bending or resting the wrists,
  • Eyes level with the computer screen.
This is a good place to start, regardless if you sit in a chair, on a stool or a stability ball. That said, it’s not the only thing you can do to fix your body at your workstation.
Another thing to think about is using a standing desk.
According to Dr. Edward R. Laskowski and the Mayo Clinic, sitting can be really bad for your health. People who sit for long periods of time are more prone to increased blood pressure, high cholesterol, diabetes, obesity, and cancer.
Even if you switch to a standing desk for just a few hours a day, you can increase the number of calories burned and stave off some of those health issues. In a study conducted back in 2011, researchers found additional health benefits when using a standing desk:
“The Take-a-Stand Project reduced time spent sitting by 224% (66 minutes per day), reduced upper back and neck pain by 54% and improved mood states.”
You don’t need to go investing in a standing desk to make this change. They can be expensive, especially when you already have a setup you’re comfortable with. However, what you can do is invest in a riser.

Not only can I adjust the height of the riser, but I can tilt it, too. This is useful not just for turning my desk into a standing desk setup, but I can take this with me when I work in hotels to make sure I’m always maintaining proper alignment.

Use Time-Blocking To Schedule Your Day

Usually when people recommend the Pomodoro Technique — developed by Francesco Cirillo — they’re going to tell you to break your day into 25-minute intervals. That’s not really what the goal of this time management method is though.
The reason you break your workday into blocks is because it’s easier to focus when you have a clear and reasonable end-time in sight. It’s also useful for structuring your day.
For someone like a salesperson who has to get on call after call with leads or to sit in an endless string of meetings, half-hour blocks make a whole lot of sense. That’s naturally how their day breaks apart. Web designers would benefit from much longer blocks. Here’s why:
A study from the University of California and Humboldt University looked at what happens after work is disrupted. These were their findings and interpretations:
“When people are constantly interrupted, they develop a model of working faster (and writing less) to compensate for the time they know they will lose by being interrupted. Yet working faster with interruptions has its cost: people in the interrupted conditions experienced a higher workload, more stress, higher frustration, more time pressure and effort. So interrupted work may be done faster, but at a price.”
You have to be careful about managing the “cost” of taking a break. 25-minute blocks are just too costly for a web designer. I’d recommend looking at how your tasks naturally break apart.
Would prototyping a landing page take an hour or two? How about research and planning? Take a close look at the tasks you commonly perform and how long they take, on average, to complete.
I’d also look at where you naturally start to “fail” and lose focus. It’s the same thing that happens in workouts — when you reach your breaking point, your body just gives up. Unfortunately, some people try to push through it when it’s the brain screaming, “Stop!”
Another thing to look at is where your peak energy hours are. We all have them. For me, it’s between 2 PM and 5 PM every day. I always schedule my hardest projects then.
Use those as benchmarks for your blocks. On top of creating blocks and breaks throughout the workday, also be sure to set dedicated hours and limits for yourself. It’s a lot harder to get fatigued if you know you only have to put in a specific number of hours of work that day.
As for building this out, use a tool that makes it easy to set recurring breaks and stick to the same schedule every day. It could be as simple as using your Google Calendar:

Whatever you choose, make sure you can slot in each task by time and color-code tasks based on things like client, priority, type, design stage, etc.

Get Outside During The Workday

Okay, so let’s talk about what you should be doing with your scheduled breaks.
Unless there’s a dangerous storm outside, you should make an effort to get outside at least once a day. There are a ton of health benefits associated with sunlight, including an increase in vitamin D and serotonin.
Vitamin D is useful as it helps increase our immune systems and fight off disease. If you’ve ever tried to work while battling a cold or the flu, you know how difficult that can be — especially when your bed is just a matter of steps away.
Serotonin is also useful for work. Serotonin is what gives us the energy and good mood to power through longer days. Melatonin, on the other hand, is what puts us soundly to sleep at night. If we don’t get the right balance of it — which can happen if you’re stuck inside with artificial lighting all day — you could end up with sleepless nights and exhausting days.

According to Russel J. Reiter, a melatonin researcher:
“The light we get from being outside on a summer day can be a thousand times brighter than we’re ever likely to experience indoors. For this reason, it’s important that people who work indoors get outside periodically and moreover that we all try to sleep in total darkness. This can have a major impact on melatonin rhythms and can result in improvements in mood, energy and sleep quality.”
But it’s not just sunlight and fresh air that help with energy and productivity. Exercise is important, too. And what better way to fit in fitness than when you’re already outside and on a break from work?
For some people, taking a long walk is their preferred mode of outdoor exercise. It’s also a great option if you’re a dog owner and want to give them a big dose of exercise at the same time.
Ann Green, a fitness studio owner, yoga teacher and heptathlon world athlete, explains the benefits of walking:
“There are many reasons to walk for exercise. Walking improves fitness, cardiac health, alleviates depression and fatigue, improves mood, creates less stress on joints and reduces pain, can prevent weight gain, reduce the risk for cancer and chronic disease, improve endurance, circulation and posture and the list goes on.”
If you want something a little more exhilarating without breaking a major sweat in the middle of the workday, why not take an electric bike out?
There are many great things about this option. For starters, because e-bikes (like the ones you get from Rad Power Bikes) take some of the work out of pedaling for you, you can ride for a lot longer and go further.
Researchers at the University of Colorado conducted a study with 20 volunteers to see what would happen when they traded their car for an e-bike when commuting to work. Their objective was to ride for at least 40 minutes, three times a week, for a full month.
They found that electric bikes had improved their:
  • Cardiovascular health,
  • Aerobic capacity,
  • Blood sugar control.
Another reason an e-bike is an attractive option is because you can use it for a variety of purposes.
You can use it for commuting, if you have an office you work out of. You can use it for general exercise whenever you feel like it. You can also use it to get more done during your breaks. If you ever feel stressed out about when you’re going to have time to pick up groceries, for instance, an e-bike would be a great way to knock out your exercise and chores all at once.
Bottom line:
You’re carving time out of your workday to get away from your computer and give your brain and body a rest so it can recharge. Don’t waste it by putting yourself in front of another screen. If you can get outside, not only will you improve your overall health, but you’ll give yourself an instant boost of energy and mood, too.

Wrapping Up

Just because working indoors, at a desk, in front of a computer screen has been known to cause issues, that doesn’t mean you can’t take steps to lessen or remove those negative side effects from your workday.
Focus and energy are both very important in your line of work. By making just a few small adjustments, you can ensure that both remain high while you’re desk-side.



Thursday, October 24, 2019

Getting Started With Axios In Nuxt

In this tutorial, we will learn how to make a request in our Nuxt.js applications using the Axios module. We will also learn how to use the ayncData and fetch methods to fetch data on the server-side using Axios and the differences between the two methods. Finally, we will learn how to add authentication to our application using the Auth module.
Nuxt.js provides an Axios module for easy integration with your application. Axios is a promise-based HTTP client that works in the browser and Node.js environment or, in simpler terms, it is a tool for making requests (e.g API calls) in client-side applications and Node.js environment.
In this tutorial, we’re going to learn how to use the Axios module and how to make a request on the server-side using asyncData and fetch. These two methods make a request on the server-side but they have some differences which we’re also going to cover. Finally, we’ll learn how to perform authentication and secure pages/routes using the auth module and auth middleware.
This article requires basic knowledge of Nuxtjs and Vuejs as we’ll be building on top of that. For those without experience with Vuejs, I recommend you start from their official documentation and the Nuxt official page before continuing with this article.

What Is The Nuxt.js Axios Module?

According to the official Documentation,
“It is a Secure and easy Axios integration with Nuxt.js.”
Here are some of its features:
  1. Automatically set base URL for client-side & server-side.
  2. Proxy request headers in SSR (Useful for auth).
  3. Fetch Style requests.
  4. Integrated with Nuxt.js Progressbar while making requests.
To use the axios module in your application, you will have to first install it by using either npm or yarn.
YARN
yarn add @nuxtjs/axios
NPM
npm install @nuxtjs/axios
Add it into your nuxt.config.js file:
modules: [
    '@nuxtjs/axios',
  ],

  axios: {
    // extra config e.g
    // BaseURL: 'https://link-to-API'
  }
The modules array accepts a list of Nuxt.js modules such as dotenv, auth and in this case, Axios. What we’ve done is to inform our application that we would be using the Axios module, which we reference using @nuxtjs/axios. This is then followed by the axios property which is an object of configurations like the baseURL for both client-side and server-side.
Now, you can access Axios from anywhere in your application by calling this.$axios.method or this.$axios.$method. Where method can be get, post, or delete.


Making Your First Request Using Axios


After cloning the repo and opening the start folder, we would need to install all our packages in the package.json file so open your terminal and run the following command:
npm install
Once that is done, we can start our app using the npm run dev command. This is what you should see when you go to localhost:3000.

The next thing we have to do is to create a .env file in the root folder of our application and add our API URL to it. For this tutorial, we’ll be using a sample API built to collect reports from users.
API_URL=https://ireporter-endpoint.herokuapp.com/api/v2/
This way, we do not have to hard code our API into our app which is useful for working with two APIs (development and production).
The next step would be to open our nuxt.config.js file and add the environmental variable to our axios config that we added above.
/*
   ** Axios module configuration
   */
  axios: {
    // See https://github.com/nuxt-community/axios-module#options
    baseURL: process.env.API_URL,
  },
Here, we tell Nuxt.js to use this baseURL for both our client-side and server-side requests whenever we use this Axios module.
Now, to fetch a list of reports, let us open the index.vue file and add the following method to the script section.
async getIncidents() {
  let res = await this.$store.dispatch("getIncidents");
  this.incidents = res.data.data.incidents;
}
What we have done is to create an async function that we call getIncidents() and we can tell what it does from the name — it fetches a list of incidents using the Vuex store action method this.$store.dispatch. We assign the response from this action to our incidents property so we can be able to make use of it in the component.
We want to call the getIncidents() method whenever the component mounts. We can do that using the mounted hook.
mounted() {
    this.getIncidents()
  }
mounted() is a lifecycle hook that gets called when the component mounts. That will cause the call to the API to happen when the component mounts. Now, let us go into our index.js file in our store and create this action where we’ll be making our Axios request from.
export const actions = {
  async getIncidents() {
    let res = await this.$axios.get('/incidents')
    return res;
  }
}
Here, we created the action called getIncidents which is an async function, then we await a response from the server and return this response. The response from this action is sent back to our getIncidents() method in our index.vue file.
If we refresh our application, we should now be able to see a long list of incidents rendered on the page.

We have made our first request using Axios but we won’t stop there, we are going to be trying out asyncData and fetch to see the differences between them and using Axios.

AsyncData

AsyncData fetches data on the server-side and it’s called before loading the page component. It does not have access to this because it is called before your page component data is created. this is only available after the created hook has been called so Nuxt.js automatically merges the returned data into the component’s data.
Using asyncData is good for SEO because it fetches your site’s content on the server-side and also helps in loading content faster. Note that asyncData method can only be used in the pages folder of your application as it would not work in the components folder. This is because asyncData hook gets called before your component is created.

Let us add asyncData to our index.vue file and observe how fast our incidents data loads. Add the following code after our components property and let us get rid of our mounted hook.
async asyncData({ $axios }) {
    let { data } = await $axios.get("/incidents");
    return { incidents: data.data.incidents };
  },
  // mounted() {
  //   this.getIncidents();
  // },
Here, the asyncData method accepts a property from the context $axios. We use this property to fetch the list of incidents and the value is then returned. This value is automatically injected into our component. Now, you can notice how fast your content loads if you refresh the page and at no time is there no incident to render.

Fetch

The Fetch method is also used to make requests on the server-side. It is called after the created hook in the life cycle which means it has access to the component’s data. Unlike the asyncData method, the fetch method can be used in all .vue files and be used with the Vuex store. This means that if you have the following in your data function.
data() {
    return {
      incidents: [],
      id: 5,
      gender: 'male'
    };
}
You can easily modify id or gender by calling this.id or this.gender.

Using Axios As A Plugin

During the process of development with Axios, you might find that you need extra configuration like creating instances and interceptors for your request so your application can work as intended and thankfully, we can do that by extending our Axios into a plugin.
To extend axios, you have to create a plugin (e.g. axios.js) in your plugins folder.
export default function ({
  $axios,
  store,
  redirect
}) {
  $axios.onError(error => {
    if (error.response && error.response.status === 500) {
      redirect('/login')
    }
  })
  $axios.interceptors.response.use(
    response => {
      if (response.status === 200) {
        if (response.request.responseURL && response.request.responseURL.includes('login')) {
          store.dispatch("setUser", response);
        }
      }
      return response
    }
  )
}
This is an example of a plugin I wrote for a Nuxt application. Here, your function takes in a context object of $axios, store and redirect which we would use in configuring the plugin. The first thing we do is to listen for an error with a status of 500 using $axios.onError and redirect the user to the login page.
We also have an interceptor that intercepts every request response we make in our application checks if the status of the response we get is 200. If that is true we proceed and check that there is a response.request.responseURL and if it includes login. If this checks out to be true, we then send this response using our store’s dispatch method where it then mutated in our state.
Add this plugin to your nuxt.config.js file:
plugins: [
    '~/plugins/axios'
  ]
After doing this, your Axios plugin would intercept any request you make and check if you have defined a special case for it.

Introduction To The Auth Module

The auth module is used for performing authentication for your Nuxt application and can be accessed from anywhere in your application using $this.auth. It is also available in fetch, asyncData, middleware and NuxtInitServer from the context object as $auth.
The context provides additional objects/params from Nuxt to Vue components and is available in special nuxt lifecycle areas like those mentioned above.
To use the auth module in your application, you would have to install it using yarn or npm.
YARN
yarn add @nuxtjs/auth
NPM
npm install @nuxtjs/auth
Add it to your nuxt.config.js file.
modules: [
  '@nuxtjs/auth'
],
auth: {
  // Options
}
The auth property accepts a list of properties such as strategies and redirect. Here, strategies accepts your preferred authentication method which can be:
  • local
    For username/email and password-based flow.
  • facebook
    For using Facebook accounts as a means of authentication.
  • Github
    For authenticating users with Github accounts.
  • Google
    For authenticating users with Google accounts.
  • Auth0
  • Laravel Passport
The redirect property accepts an object of links for:
  • login
    Users would be redirected to this link if login is required.
  • logout
    Users would be redirected here if after logout current route is protected.
  • home
    Users would be redirected here after login.
Now, let us add the following to our nuxt.config.js file.
/*
 ** Auth module configuration
 */
auth: {
  redirect: {
    login: '/login',
    logout: '/',
    home: '/my-reports'
  },
  strategies: {
    local: {
      endpoints: {
        login: {
          url: "/user/login",
          method: "post",
          propertyName: "data.token",
        },
        logout: false,
        user: false,
      },
      tokenType: '',
      tokenName: 'x-auth',
      autoFetchUser: false
    },
  },
}
Please note that the auth method works best when there is a user endpoint provided in the option above.
Inside the auth config object, we have a redirect option in which we set our login route to /login, logout route to / and home route to /my-reports which would all behave as expected. We also have a tokenType property which represents the Authorization type in the header of our Axios request. It is set to Bearer by default and can be changed to work with your API.
For our API, there is no token type and this is why we’re going to leave it as an empty string. The tokenName represents the Authorization name (or the header property you want to attach your token to) inside your header in your Axios request.
By default, it is set to Authorization but for our API, the Authorization name is x-auth. The autoFetchUser property is used to enable user fetch object using the user endpoint property after login. It is true by default but our API does not have a user endpoint so we have set that to false.
For this tutorial, we would be using the local strategy. In our strategies, we have the local option with endpoints for login, user and logout but in our case, we would only use the *login* option because our demo API does not have a *logout* endpoint and our user object is being returned when *login* is successful.
Note: The auth module does not have a register endpoint option so that means we’re going to register the traditional way and redirect the user to the login page where we will perform the authentication using this.$auth.loginWith. This is the method used in authenticating your users. It accepts a ‘strategy’ (e.g local) as a first argument and then an object to perform this authentication with. Take a look at the following example.
let data {
          email: 'test@test.com',
          password: '123456'
}
this.$auth.loginWith('local', { data })

Using The Auth Module

Now that we have configured our auth module, we can proceed to our registration page. If you visit the /register page, you should see a registration form.

Let us make this form functional by adding the following code:
methods: {
  async registerUser() {
    this.loading = true;
    let data = this.register;
    try {
      await this.$axios.post("/user/create", data);
      this.$router.push("/login");
      this.loading = false;
      this.$notify({
        group: "success",
        title: "Success!",
        text: "Account created successfully"
      });
    } catch (error) {
      this.loading = false;
      this.$notify({
        group: "error",
        title: "Error!",
        text: error.response
          ? error.response.data.error
          : "Sorry an error occured, check your internet"
      });
    }
  }
}
Here, we have an async function called registerUser which is tied to a click event in our template and makes an Axios request wrapped in a try/catch block to an endpoint /user/create. This redirects to the /login page and notifies the user of a successful registration. We also have a catch block that alerts the user of any error if the request is not successful.
If the registration is successful, you would be redirected to the login page.

Here, we’re going to make use of auth authentication method this.$auth.loginWith('local', loginData) after which we would use the this.$auth.setUser(userObj) to set the user in our auth instance.
To get the login page working, let’s add the following code to our login.vue file.
methods: {
  async logIn() {
    let data = this.login;
    this.loading = true;
    try {
      let res = await this.$auth.loginWith("local", {
        data
      });
      this.loading = false;
      let user = res.data.data.user;
      this.$auth.setUser(user);
      this.$notify({
        group: "success",
        title: "Success!",
        text: "Welcome!"
      });
    } catch (error) {
      this.loading = false;
      this.$notify({
        group: "error",
        title: "Error!",
        text: error.response
          ? error.response.data.error
          : "Sorry an error occured, check your internet"
      });
    }
  }
}
We created an async function called logIn using the auth method this.$auth.loginWith('local, loginData). If this login attempt is successful, we then assign the user data to our auth instance using this.$auth.setUser(userInfo) and redirect the user to the /my-report page.
You can now get user data using this.$auth.user or with Vuex using this.$store.state.auth.user but that’s not all. The auth instance contains some other properties which you can see if you log in or check your state using your Vue dev tools.
If you log this.$store.state.auth to the console, you’ll see this:
{
  "auth": {
    "user": {
      "id": "d7a5efdf-0c29-48aa-9255-be818301d602",
      "email": "tmxo@test.com",
      "lastName": "Xo",
      "firstName": "Tm",
      "othernames": null,
      "isAdmin": false,
      "phoneNumber": null,
      "username": null
    },
    "loggedIn": true,
    "strategy": "local",
    "busy": false
  }
}
The auth instance contains a loggedIn property that is useful in switching between authenticated links in the nav/header section of your application. It also contains a strategy method that states the type of strategy the instance is running (e.g local).
Now, we will make use of this loggedIn property to arrange our nav links. Update your navBar component to the following:
<template>
  <header class="header">
    <div class="logo">
      <nuxt-link to="/">
        <Logo />
      </nuxt-link>
    </div>
    <nav class="nav">
      <div class="nav__user" v-if="auth.loggedIn">
        <p>{{ auth.user.email }}</p>
        <button class="nav__link nav__link--long">
          <nuxt-link to="/report-incident">Report incident</nuxt-link>
        </button>
        <button class="nav__link nav__link--long">
          <nuxt-link to="/my-reports">My Reports</nuxt-link>
        </button>
        <button class="nav__link" @click.prevent="logOut">Log out</button>
      </div>
      <button class="nav__link" v-if="!auth.loggedIn">
        <nuxt-link to="/login">Login</nuxt-link>
      </button>
      <button class="nav__link" v-if="!auth.loggedIn">
        <nuxt-link to="/register">Register</nuxt-link>
      </button>
    </nav>
  </header>
</template>
<script>
import { mapState } from "vuex";
import Logo from "@/components/Logo";
export default {
  name: "nav-bar",
  data() {
    return {};
  },
  computed: {
    ...mapState(["auth"])
  },
  methods: {
    logOut() {
      this.$store.dispatch("logOut");
      this.$router.push("/login");
    }
  },
  components: {
    Logo
  }
};
</script>
<style></style>
In our template section, we have several links to different parts of the application in which we are now using auth.loggedIn to display the appropriate links depending on the authentication status. We have a logout button that has a click event with a logOut() function attached to it. We also display the user’s email gotten from the auth property which is accessed from our Vuex store using the mapState method which maps our state auth to the computed property of the nav component. We also have a logout method that calls our Vuex action logOut and redirects the user to the login page.
Now, let us go ahead and update our store to have a logOut action.
export const actions = {
    // ....
  logOut() {
    this.$auth.logout();
  }
}
The logOut action calls the auth logout method which clears user data, deletes tokens from localStorage and sets loggedIn to false.
Routes like /my-reports and report-incident should not be visible to guests but at this point in our app, that is not the case. Nuxt does not have a navigation guard that can protect your routes, but it has is the auth middleware. It gives you the freedom to create your own middleware so you can configure it to work the way you want.
It can be set in two ways:
  1. Per route.
  2. Globally for the whole app in your nuxt.config.js file.
router: {
  middleware: ['auth']
}
This auth middleware works with your auth instance so you do not need to create an auth.js file in your middleware folder.
Let us now add this middleware to our my-reports.vue and report-incident.vue files. Add the following lines of code to the script section of each file.
middleware: 'auth'
Now, our application would check if the user trying to access these routes has an auth.loggedIn value of true. It’ll redirect them to the login page using our redirect option in our auth config file — if you’re not logged in and you try to visit either /my-report or report-incident, you would be redirected to /login.


This page is for adding incidents but that right now the form does not send incident to our server because we are not making the call to the server when the user attempts to submit the form. To solve this, we will add a reportIncident method which will be called when the user clicks on Report. We’ll have this in the script section of the component. This method will send the form data to the server. Update your report-incident.vue file with the following:
<template>
  <section class="report">
    <h1 class="report__heading">Report an Incident</h1>
    <form class="report__form">
      <div class="input__container">
        <label for="title" class="input__label">Title</label>
        <input
          type="text"
          name="title"
          id="title"
          v-model="incident.title"
          class="input__field"
          required
        />
      </div>
      <div class="input__container">
        <label for="location" class="input__label">Location</label>
        <input
          type="text"
          name="location"
          id="location"
          v-model="incident.location"
          required
          class="input__field"
        />
      </div>
      <div class="input__container">
        <label for="comment" class="input__label">Comment</label>
        <textarea
          name="comment"
          id="comment"
          v-model="incident.comment"
          class="input__area"
          cols="30"
          rows="10"
          required
        ></textarea>
      </div>
      <input type="submit" value="Report" class="input__button" @click.prevent="reportIncident" />
      <p class="loading__indicator" v-if="loading">Please wait....</p>
    </form>
  </section>
</template>
<script>
export default {
  name: "report-incident",
  middleware: "auth",
  data() {
    return {
      loading: false,
      incident: {
        type: "red-flag",
        title: "",
        location: "",
        comment: ""
      }
    };
  },
  methods: {
    async reportIncident() {
      let data = this.incident;
      let formData = new FormData();
      formData.append("title", data.title);
      formData.append("type", data.type);
      formData.append("location", data.location);
      formData.append("comment", data.comment);
      this.loading = true;
      try {
        let res = await this.$store.dispatch("reportIncident", formData);
        this.$notify({
          group: "success",
          title: "Success",
          text: "Incident reported successfully!"
        });
        this.loading = false;
        this.$router.push("/my-reports");
      } catch (error) {
        this.loading = false;
        this.$notify({
          group: "error",
          title: "Error!",
          text: error.response
            ? error.response.data.error
            : "Sorry an error occured, check your internet"
        });
      }
    }
  }
};
</script>
<style>
</style>
Here, we have a form with input fields for title, location, and comment with two-way data binding using v-model. We also have a submit button with a click event. In the script section, we have a reportIncident method that collects all the information provided in the form and is sent to our server using FormData because the API is designed to also accept images and videos.
This formData is attached to a Vuex action using the dispatch method, if the request is successful, you get redirected to /my-reports with a notification informing you that this request was successful otherwise, you would be notified of an error with the error message.
At this point, we don’t have reportIncident action in our store yet so in your browser console, you would see an error if you try to click submit on this page.

To fix this, add the reportIncident action your index.js file.
   
export const actions = {
  // ...
  async reportIncident({}, data) {
    let res = await this.$axios.post('/incident/create', data)
    return res;
  }
}
Here, we have a reportIncident function that takes in an empty context object and the data we’re sending from our form. This data is then attached to a post request that creates an incident and returns back to our report-incident.vue file.
At this point, you should be able to add a report using the form after which you would be redirected to /my-reports page.

This page should display a list of incidents created by the user but right now it only shows what we see above, let’s go ahead to fix that.
We’re going to be using the fetch method we learned about to get this list. Update your my-reports.vue file with the following:
<script>
import incidentCard from "@/components/incidentCard.vue";
export default {
  middleware: "auth",
  name: "my-reports",
  data() {
    return {
      incidents: []
    };
  },
  components: {
    incidentCard
  },
  async fetch() {
    let { data } = await this.$axios.get("/user/incidents");
    this.incidents = data.data;
  }
};
</script>
Here, we use fetch method to get user-specific incidents and assign the response to our incidents array.

At this point, we would notice a difference in how fetch method and asyncData loads our data.

Conclusion

So far, we have learned about the Axios module and all of its features. We have also learned more about asyncData, and how we can fetch both of them together despite their differences. We’ve also learned how to perform authentication in our application using the auth module and how to use the auth middleware to protect our routes. Here are some useful resources that talk more about all we’ve covered.

Resources

  1. Auth Module,” NuxtJS.org
  2. Axios Module: Introduction,” NuxtJS.org
  3. FormData, MDN web docs
  4. API: The asyncData Method,” NuxtJS.org
  5. The Vue Instance: Lifecycle Diagram,” VueJS.org
  6. Understanding How fetch Works In Nuxt 2.12,” NuxtJS.org