I have a Vue application which communicates with API (using axios requests) and return error(s).
It works fine if I get only one error, for example when response is like this: {"error":"passwords.token"}
When i'm getting cumulated errors like this:
{"message":"The given data was invalid.",
"errors":{
"password":["The password confirmation does not match."]}
}
Here is my code of my Vue component and method resetPassword()
methods: {
resetPassword () {
this.$vs.loading()
const payload = {
userDetails: {
email: this.email,
password: this.password,
password_confirmation: this.password_confirmation,
token: this.token
}
}
this.$store.dispatch('auth/resetPassword', payload)
.then((response) => {
this.$vs.loading.close()
this.$vs.notify({
time: 10000,
title: 'Authentication Success',
text: response.message.data.message,
iconPack: 'feather',
icon: 'icon-success-circle',
color: 'success'
})
})
.catch(error => {
this.$vs.loading.close()
this.$vs.notify({
time: 6000,
title: 'Authentication Error',
text: error.message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
})
},
},
I guess that the issue is that when you have more than one error, you only see one message The given data was invalid
.
Here is why:
Whit this syntax:
"errors":{
"password":["The password confirmation does not match."]}
}
You are not using the error.message properly, as you use in the notify call:
this.$vs.notify({
time: 6000,
title: 'Authentication Error',
text: error.message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
What you can do is return the same array of errors always, even if you have one error or ten errors:
"errors": [
{
type: "password",
message: "Wrong password"
},
{
type: "user",
message: "Wrong user"
},
// As recommendation, notify only "Authentication error", instead the specific field
{
type: "Authentication error",
message: "Wrong credentials"
},
]
And you can notify this way:
.catch(error => { // You return errors inside error object
const errors = error.errors; // and you can get it here
// const { errors } = error; // alternative syntax
for (let err on errors) {
this.$vs.notify({
time: 6000,
title: 'Authentication Error', // You can use err.type
text: err.message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
}
}
Alternative for:
.catch(error => { // You return errors inside error object
const errors = error.errors; // and you can get it here
// const { errors } = error; // alternative syntax
for (let i = 0; i < errors.length; i++) {
this.$vs.notify({
time: 6000,
title: 'Authentication Error', // You can use errors[i].type
text: errors[i].message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
}
}
If you want to keep the structure in your error response, then check what kind of response are you getting and send the notification:
.catch(err => { // You return errors inside error object
const { error, errors } = err;
if (error) { // only one error
this.$vs.notify({
time: 6000,
title: 'Authentication Error',
text: error.message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
} else {
for (let errorType of errors) { // more than one error
this.$vs.notify({
time: 6000,
title: 'Authentication Error',
text: errors[errorType][0],
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
})
}
}
}
It's not a good idea this approach, but if you want to use it, then it's fine.