0
votes

I'm having a problem with validation when it comes to Laravel and Vue

My controller has logic like this.

$this->validate($request, [
    "name" =>   ["required", "min:3"]
]);

Vue only recognizes one of the two validations, however. For example, if the text field isn't at least 3 characters long Vue will still allow all to go through, claiming that the name field is still required.

The only error that displays on the front end is the "required" rule, there's nothing there for "min:3".

Any advice? Or if anyone can lead me to a good source with VueJS/Laravel validation that would be awesome too,

thanks in advance.

Another odd thing is that though the name field is required even if it is fulled in, Laravel still returns that error in the console 422.

VueJS Component

<template>
    <!-- Third paramater in v-bind="" class will be used in either -->
    <div>
        <form v-on:submit.prevent>
            <div class="section">
                <div class="field level">
                    <p class="control has-text-centered">
                        <input
                            id="name"
                            name="name"
                            v-model="item.name"
                            class="input is-rounded is-large"
                            type="text"
                            placeholder="Enter Todo.."
                            v-bind:class="[
                                item.name ? 'is-success' : 'is-normal',
                                'plus'
                            ]"
                        />
                    </p>
                </div>
                <div class="alert alert-danger" v-if="errors && errors.name">
                    {{ errors.name[0] }}
                </div>
                <button
                    @click="addItem()"
                    class="button is-primary is-fullwidth"
                >
                    <font-awesome-icon
                        icon="plus-square"
                        class="color is-primary"
                    />
                </button>
            </div>
        </form>
    </div>
</template>

<script>
export default {
    data: function() {
        return {
            item: {
                name: ""
            },

            errors: {}
        };
    },

    methods: {
        addItem() {
            // if (this.item.name === "") {
            //     return;
            // }
            axios
                .post("api/item/store", {
                    item: this.item
                })
                .then(response => {
                    if (response.status == 201) {
                        this.item.name = "";
                        this.$emit("reloadlist");
                        this.errors = {};
                    }
                })
                .catch(error => {
                    if (error.response.status == 422) {
                        this.errors = error.response.data.errors;
                    }
                    console.log(error);
                });
        }
    }
};
</script>

<style scoped>
p {
    margin: auto;
}
</style>

PHP Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Item;
use Illuminate\Support\Carbon;

class ItemsController extends Controller
{
    /**
     * Display a listing of the item resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return Item::orderBy("created_at", "DESC")->get();
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            "name" =>   ["required", "min:3"]
        ]);

        $newItem = new Item;

        $newItem->name = $request->item["name"];

        $newItem->save();
        dd("Hello, World");
        return $newItem;
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $existingItem = Item::find($id);

        if ($existingItem) {
            $existingItem->completed = $request->item["completed"] ? true : false;
            $existingItem->completed_at = $request->item["completed"] ? Carbon::now() : null;

            $existingItem->save();

            return $existingItem;
        }

        return "Item not found.";
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $existingItem = Item::find($id);

        if ($existingItem) {
            $existingItem->delete();

            return "Item '{$existingItem->name}' deleted successfully.";
        }

        return "Item not found.";
    }
}
1
Sounds like you're not getting the object properly passed into the controller, have you verified? Try putting dd($request->all()); at the beginning of the store method and make sure you're getting the name property correctly.Andrew
you passed item parameter in your axios.post but you checked your request for name parameter, so it will never match.Anurat Chapanond

1 Answers

2
votes

Item is already an object so you dont need it to put in an object variable and the name it item.

Change your axios request to:

methods: {
        addItem() {
            // if (this.item.name === "") {
            //     return;
            // }
            axios
                .post("api/item/store", this.item)
                .then(response => {
                    if (response.status == 201) {
                        this.item.name = "";
                        this.$emit("reloadlist");
                        this.errors = {};
                    }
                })
                .catch(error => {
                    if (error.response.status == 422) {
                        this.errors = error.response.data.errors;
                    }
                    console.log(error);
                });
        }
    }

I think this will solve your problem.