来自Vue组件的laravel表单请求上的422响应没有错误消息

时间:2018-07-27 17:57:54

标签: laravel vuejs2 axios

我正在尝试使用axios提交表单请求,对其进行验证,如果验证失败,则返回错误。问题是,当我提交表单时,不会返回任何错误消息供我在客户端显示。这是 HTTP请求和vue组件:      

         <div class="card">
            <div class="card-header">
                    <h4>Information</h4>
            </div>

        <div class="card-body">
            <p v-if='!isEditMode'><strong>Name:</strong> {{businessData.name}}</p> 
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-name">Name</label></strong> 
                <input class="form-control" name="business-name"  v-model='businessData.name'>
            </div>
            <p v-if='!isEditMode'><strong>Description:</strong> {{businessData.description}}</p> 
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-description">Description</label></strong> 
                <textarea class="form-control normal" name="business-description" 
                    placeholder="Enter your services, what you sell, and why your business is awesome" 
                    v-model='businessData.description'></textarea>
            </div>
        </div>

    </div>

    <div class="card">
        <h4 class="card-header">Address Information</h4>
        <div class="card-body">

            <p v-if="!isEditMode"><strong>Street Address: </strong> {{businessData.street}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-street">Street Address: </label></strong> 
                <input type="text" class="form-control" name="business-street"  v-model='businessData.street' placeholder="1404 e. Local Food Ave">
            </div>
            <p v-if="!isEditMode"><strong>City: </strong> {{businessData.city}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-city">City: </label></strong> 
                <input class="form-control" type="text" name="business-city"  v-model='businessData.city'>
            </div>
            <p v-if="!isEditMode"><strong>State: </strong> {{businessData.state}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-state">State: </label></strong> 
                <select class="form-control" name="business-state"  id="state" v-model="businessData.state" >...</select>                                 
            </div>
            <p v-if="!isEditMode"><strong>Zip: </strong> {{businessData.zip}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-zip">Zip: </label></strong> 
                <input class="form-control" type="text" maxlength="5" name="business-zip"  v-model='businessData.zip'>
            </div>

        </div>
    </div>
    <div class="card">
        <h4 class="card-header">Contact Information</h4>
        <div class="card-body">
            <p v-if="!isEditMode"><strong>Phone: </strong> {{businessData.phone}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-phone">Phone: </label></strong> 
                <input class="form-control" type="tel" name="business-phone"  v-model='businessData.phone'>
            </div>
            <p v-if="!isEditMode"><strong>Email: </strong> {{businessData.email}}</p>
            <div class="form-group" v-if='isEditMode'>
                <strong><label for="business-Email">Email: </label></strong> 
                <input class="form-control" type="email" name="business-email"  v-model='businessData.email'>
            </div>
        </div>
    </div>
</div>
<script>
export default {
    data () {
        return {
            isEditMode: false,
            businessData: this.business,
            userData: this.user,
            errors: []
        }
    },
    props: {
        business: {},
        user: {},
        role: {}
    },
    //Todo - Institute client side validation that prevents submission of faulty data
    methods: {
        validateData(data) {

        },
        saveBusinessEdits () {
            axios.put('/businesses/' + this.business.id , {updates: this.businessData})
            .then(response => {
                console.log(response.data)
                // this.businessData = response.data;
                this.isEditMode = false;
            })
            .catch (response => {
                console.log(response.data)
                this.isEditMode = false;
            })
        },
        saveUserEdits () {
            axios.put('/profile/' + this.user.id , {updates: this.userData})
            .then(response => {
                console.log(response.data)
                this.userData = response.data;
                this.isEditMode = false;
            })
            .catch (response => {
                console.log(response)
                this.isEditMode = false;
            })
        }
    }
}

路线

Route::put('/businesses/{id}', 'BusinessesController@update');

BusinessController和更新功能

  public function update(BusinessRequest $request, $id)
{

    $business = Business::find($id)->update($request->updates);


    $coordinates = GoogleMaps::geocodeAddress($business->street,$business->city,$business->state,$business->zip);
        if ($coordinates['lat']) {
            $business['latitude'] = $coordinates['lat'];
            $business['longitude'] = $coordinates['lng'];
            $business->save();
            return response()->json($business,200);
        } else {                    
            return response()->json('invalid_address',406);
        }
        $business->save();
        return response()->json($business,200);
}

BusinessRequest类

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'business-name'=> 'required|string|max:255',
        'business-description'=> 'required|string',
        'business-phone' => 'nullable|phone|numeric',
        'business-email' => 'nullable|email',
        'business-street'=> 'required|string',
        'business-city' => 'required|string',
        'business-state' => 'required|string|max:2',
        'business-zip' => 'required|min:5|max:5|numeric', 
    ];
}

public function messages() {
    return [
        'business-zip.min:5' =>'your zip code must be a 5 characters long',
        'business-email.email'=>'your email is invalid',
        'business-phone.numeric'=>'your phone number is invalid',
    ];
}
}

我不明白为什么即使输入有效数据,它也会返回422响应,并且绝对没有错误消息。由于这是laravel 5.6,因此web.php文件中的所有路由中的“网络”中间件都是自动的。所以这不是问题。有人可以帮我规范化验证行为吗?

2 个答案:

答案 0 :(得分:2)

在Laravel中,422状态代码表示表单验证失败。

使用axios,传递给thencatch方法的对象实际上是不同的。要查看错误的响应,您实际上需要具有以下内容:

.catch (error => {
    console.log(error.response)
    this.isEditMode = false;
})

然后要获取错误(取决于您的Laravel版本),您将具有以下内容:

console.log(error.response.data.errors)

展望未来,值得一看Spatie's form-backend-validation package

答案 1 :(得分:0)

您可以使用Vue.js和axios验证并显示错误。在控制器中有一个名为/ validate-data的路由来验证数据。

app.js文件:

UserID  |  PPName
-----------------------   
1     |     SO
1     |     GO
1     |     PE
2     |     SO
2     |     GO
3     |     SO
3     |     GO
3     |     PE  

使用控制器中的方法创建一个名为/ validate-data的路由,执行标准验证

       import Vue           from 'vue'
        window.Vue = require('vue');
        window.axios = require('axios');

        window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

        let token = document.head.querySelector('meta[name="csrf-token"]');

        if (token) {
            window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
        } else {
            console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
        }

             class Errors {
                constructor() {
                    this.errors = {};
                }

                get(field) {
                    if (this.errors[field]) {

                        return this.errors[field][0];
                    }
                }

                record(errors) {
                    this.errors = errors;
                }

                clear(field) {
                    delete this.errors[field];
                }

                has(field) {
                    return this.errors.hasOwnProperty(field);
                }

                any() {
                    return Object.keys(this.errors).length > 0;
                }
            }

            new Vue({
             el: '#app',

                data:{
               errors: new Errors(),
              model: {
    business-name: '',
    business-description: '',
    business-phone: ''
    },
            },

        methods: {
          onComplete: function(){
              axios.post('/validate-data', this.$data.model)
                  // .then(this.onSuccess)
                  .catch(error => this.errors.record(error.response.data.errors));
           },
}
        });

);

然后使用与vue.js数据模型字段相对应的v-model在视图文件中创建输入。在其下,添加一个带有错误类(例如,基本的红色错误样式)的跨度,该类仅在存在错误的情况下显示。例如:

$this->validate(request(), [
 'business-name'=> 'required|string|max:255',
    'business-description'=> 'required|string',
    'business-phone' => 'nullable|phone|numeric',
    'business-email' => 'nullable|email',
    'business-street'=> 'required|string',
    'business-city' => 'required|string',
    'business-state' => 'required|string|max:2',
    'business-zip' => 'required|min:5|max:5|numeric'
]

请不要忘记在视图文件的页脚中包含app.js文件。记住要包括标签,然后运行npm run watch来编译vue代码。这将使您可以验证其输入字段下的所有错误。

忘记添加,有一个带有@ onclick =“ onComplete”的按钮来运行validate方法。