J
J
jazzus2018-12-07 10:46:30
Laravel
jazzus, 2018-12-07 10:46:30

How to show errors in Vue from Laravel Request?

The goal is to send data from the form and, in case of validation errors, display it on the screen using Laravel Request.
Created a ListRequest validation file with php artisan make:request command . File content:

public function rules()
    {
        return [
          'name' => 'required|string|max:50|unique',
        ];
    }

    public function messages()
    {
        return [
          'name.required' => 'Поле обязательно для заполнения',
          'name.max' => 'Не менее 50 символов',

Accordingly, when writing the form in the controller, ListRequest is now responsible for checking:
public function store(ListRequest $request)
The next step is to get error messages from the ListRequest file in VUE. How to do it?
In blade templates, Laravel received error messages through the errors variable (where Laravel automatically writes messages that did not pass the check through the ListRequest file):
@if (count($errors) > 0)
    <div class="alert alert-danger" style="text-align: center;" role="alert">
      @foreach ($errors->all() as $error)
       <b> {{ $error }}</b><br>
      @endforeach
    </div>
@endif

How to get these messages in VUE? The maximum that was achieved was the output of these messages in the console through the code:
.catch(function (error) {
                  console.log(error.response.data);

I found many options on the Internet with validation in the controller and recording errors in json, but I would not want to arrange validations in controllers when there is a separate file for validation with error messages in the global variable from Laravel errors (i.e. as in my example ). How to get messages from errors in VUE?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Sklyarov, 2018-12-07
@jazzus

You need to validate your data that comes from the client.

public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        $validator = \Validator::make($credentials, [
          'email' => 'required',
          'password' => 'required',
        ]);

        if ($validator->fails()) {
          return response()
            ->json(['errors' => $validator->errors()], 422);
        }
....
}

The code:
if ($validator->fails()) {
          return response()
            ->json(['errors' => $validator->errors()], 422);
        }

Returns to the client (in case of an error) an array of errors, with all the errors that occurred.
It works for me like this: in Login.vue there is a method that authorizes the user:
login(){
        var app = this
        var user = this.$auth.login({
            params: {
              email: app.email,
              password: app.password
            },
            success: function () {
              this.$store.dispatch('authuser/loadUserData');
            },
            error: function (err) {
              app.errors = err.response.data.errors;
            },
            rememberMe: app.remember,
            redirect: '/',
            fetchUser: true,
        });
      },

data(){
      return {
        email: null,
        password: null,
        errors: {},
        remember: true
      }
    },

Actually, if we got an error, then:
error: function (err) {
              app.errors = err.response.data.errors;
            },
add errors to the error array, then simply output this array:
<div v-if="errors" v-for="category in errors">
                <div class="m-alert m-alert--outline alert alert-danger alert-dismissible" role="alert" v-for="error in category">
                  <span>{{ error }}</span>
                </div>
              </div>

There are two loops here, since the errors array from the response will contain elements: errors_password, errors_email, and so on, each of which is an array. But you yourself can see this in the server response.
Just in case, I'm attaching the complete Login.vue file:
Login.vue
<template>
  <!-- begin:: Page -->
  <div class="m-grid m-grid--hor m-grid--root m-page">
    <div class="m-grid__item m-grid__item--fluid m-grid m-grid--hor m-login m-login--signin m-login--2 m-login-2--skin-2" id="m_login" style="background-image: url(/assets/app/media/img//bg/bg-3.jpg);">


      <div class="m-grid__item m-grid__item--fluid	m-login__wrapper">
        <div class="m-login__container">
          <div class="m-login__logo">
            <a href="#">
              <img src="/assets/demo/demo7/media/img/logo/logo.svg" style="height:70px;">
            </a>
          </div>
          <div class="m-login__signin">
            <div class="m-login__head">
              <h3 class="m-login__title">
                Авторизация
              </h3>
              <div class="m-login__desc">
                Заполните данные ниже для авторизации:
              </div>
            </div>
            <form class="m-login__form m-form" autocomplete="off" @submit.prevent="login" method="post">

              <div v-if="errors" v-for="category in errors">
                <div class="m-alert m-alert--outline alert alert-danger alert-dismissible" role="alert" v-for="error in category">
                  <span>{{ error }}</span>
                </div>
              </div>


              <div class="form-group m-form__group">
                <input type="email" id="email" class="form-control" placeholder="E-mail" v-model="email" required autofocus>
              </div>

              <div class="form-group m-form__group">
                <input type="password" id="password" class="form-control" v-model="password" placeholder="Пароль" equired>
              </div>
              <div class="row m-login__form-sub">
    						<div class="col m--align-left m-login__form-left">
    							<label class="m-checkbox  m-checkbox--focus m-checkbox--state-accent">
    							<input type="checkbox" name="remember" v-model="remember" checked="checked"> Запомнить меня
    							<span></span>
    							</label>
    						</div>
    						<div class="col m--align-right m-login__form-right">
    							<router-link :to="{ name: 'register'}" id="m_login_forget_password" class="m-link">Забыли пароль?</router-link>
    						</div>
    					</div>

              <div class="m-login__form-action">
                <button type="submit" class="btn btn-accent m-btn m-btn--pill m-btn--custom m-btn--air  m-login__btn">Авторизоваться</button>
              </div>


            </form>
          </div>
          <div class="m-login__account">
            <span class="m-login__account-msg">
            У вас еще нет аккаунта?
            </span>&nbsp;&nbsp;
            <router-link :to="{ name: 'register'}" class="m-link m-link--light m-login__account-link" style="border-bottom: 1px solid #6a6279;">
              Зарегистировать аккаунт
            </router-link>
          </div>

          <div class="m-login__forget-password">
            <div class="m-login__head">
              <h3 class="m-login__title">
                Забыли пароль?
              </h3>
              <div class="m-login__desc">
                Укажите Ваш e-mail для восстановления пароля:
              </div>
            </div>
            <form class="m-login__form m-form" action="">
              <div class="form-group m-form__group">
                <input class="form-control m-input" type="text" placeholder="Email" name="email" id="m_email" autocomplete="off">
              </div>
              <div class="m-login__form-action">
                <button id="m_login_forget_password_submit" class="btn btn-focus m-btn m-btn--pill m-btn--custom m-btn--air  m-login__btn m-login__btn--primaryr">
                  Выслать новый
                </button>
                &nbsp;&nbsp;
                <button id="m_login_forget_password_cancel" class="btn btn-outline-focus m-btn m-btn--pill m-btn--custom m-login__btn">
                  Отмена
                </button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- end:: Page -->

</template>

<script>
  import { mapState, mapActions } from 'vuex';
  export default {
    data(){
      return {
        email: null,
        password: null,
        errors: {},
        remember: true
      }
    },
    computed: mapState({
      user: state => state.authuser.user
    }),
    methods: {
      login(){
        var app = this
        var user = this.$auth.login({
            params: {
              email: app.email,
              password: app.password
            },
            success: function () {
              this.$store.dispatch('authuser/loadUserData');
            },
            error: function (err) {
              app.errors = err.response.data.errors;
            },
            rememberMe: app.remember,
            redirect: '/',
            fetchUser: true,
        });
      },

    }
  }
</script>

M
Mykola Ivashchuk, 2018-12-07
@mykolaim

When the Request fails validation, you will receive a 422 http code and a list of errors in the errors array in JSON format, for example:

{
  "errors": [
    {
      "field": "username",
      "message": "The username has already been taken."
    }
  ]
}

Accordingly, you need to parse this json and take certain actions for each error.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question