How to handle Laravel validation errors using VueJS 3, Axios, and Toast Notification
I came across a situation while working on my side project where I had to handle Laravel validation errors on the front-end application, which is built with VueJS 3. But, you might wonder why I am even writing an article about it since it seems like a straightforward task, isn’t it?
Let’s have a look at how axios
handles the errors:
axios.get('/api/users')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
// Handle the errors
console.log(error.response.data.errors);
});
By utilizing the catch
method in axios
, you can present the errors to the end-user.
If you only have one or two API calls, then handling the error messages individually might suffice. However, what if you have a dozen API calls? It would be quite cumbersome to handle the error messages for each individual request.
Thankfully, axios
offers a feature known as interceptors
which, as the name implies, intercepts requests or responses prior to being processed by then
or catch
methods.
Let’s have a look:
axios.interceptors.response.use(response => {
// Do something with the response
// For example: Only return the data
return response.data;
}, error => {
// Handle the errors
alert(error);
return Promise.reject(error);
});
Let’s implement it.
In my project, I have a file named http.js
which is an axios
helper:
import axios from 'axios';
const client = axios.create({
baseURL: import.meta.env.VITE_APP_API_URL,
withCredentials: true, // required to handle the CSRF token
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
export default client;
If you don’t already have something similar in your project, I highly recommend creating an axios
helper file, as it can save you the hassle of repeatedly importing and configuring axios
every time it’s needed.
Here how I use the http
helper:
import http from "@/services/http";
http.get('api/users');
Easy peacey.
On the other hand, I leverage the vue-toast-notification
package for displaying notifications. As a result, let’s integrate it with axios
to handle the validation errors.
First of all, you need to install vue-toast-notification - npm:
npm install vue-toast-notification@^3.0
Then create a file named notify.js
:
import { useToast } from 'vue-toast-notification';
import 'vue-toast-notification/dist/theme-sugar.css';
const $toast = useToast({
position: 'top-right',
dismissible: true,
duration: 2000,
});
export default class Notify {
static success(msg) {
$toast.success(msg);
}
static error(msg) {
$toast.error(msg);
}
}
At this point, the Notify
class can be accessed from any location within our project:
import Notify from "@/services/notify";
Notify.error("An error ocurred!");
Go back to the http.js
file and add the response interceptor as follows:
import Notify from "@/services/ui/notify";
client.interceptors.response.use(response => {
return response;
}, error => {
if (error.response.status === 422 && error.response.data?.errors) {
Notify.error(Object.values(error.response.data.errors).flat().join("\n"));
}
return Promise.reject(error);
});
export default client;
Moving forward, the interceptor will manage all validation error messages and present them to the end-user in an appealing manner.
Please note that you can still access the error
object within the catch
method, which is why I am returning the Promise.reject
.
That’s it.