Home > Software design >  Vue - Edit and create in same form
Vue - Edit and create in same form

Time:11-06

In Laravel i try to send some data to Vue component. If user go to component from edit URL we sent an array, if we go from create URL we send null. Like this.

Blade view

 <section id="app">
        <people-form-component :person="{{$person ?? 'null'}}"></people-form-component>
    </section>

This process is correct, dd shows data if has data, show null in other case.

Data array

{"id":1,"created_at":"2021-11-05T19:03:14.000000Z","updated_at":"2021-11-05T19:03:14.000000Z","name":"Eduardo Montoya","lastname":"Jurado","age":83,"dni":"19282246N","email":"[email protected]","id_car":8}

Then i try to get this prop and check it in component to show/hide texts and call functions.

People form component (Sorry for paste all code, but i think is necessary)

  <template>
    <div class="center">
        <div
            class="w-1/2 bg-white rounded p-8 m-6 shadow-md rounded hover:shadow-2xl transition duration-500 ease-in-out">
            <h1 class="block w-full text-center text-gray-800 text-2xl font-bold mb-6">
               {{this.person!=''? 'Update' :'Create'}}</h1>
            <div v-if="errors" class="bg-red-500 text-white py-2 px-4 pr-0 rounded font-bold mb-4 shadow-lg">
                <div v-for="(v, k) in errors" :key="k">
                    <p v-for="error in v" :key="error" class="text-sm">
                        {{ error }}
                    </p>
                </div>
            </div>
            <div class="grid-4">
                <label class="label" for="name">Name</label>
                <input class="formInput" type="text" name="name" v-model="form.name" maxlength="50"
                    placeholder="Name...">
            </div>
            <div class="grid-4">
                <label class="label" for="last_name">Last Name</label>
                <input class="formInput" type="text" name="lastname" v-model="form.lastname" maxlength="12"
                    placeholder="Lastname...">
            </div>
            <div class="grid-4">
                <label class="label" for="age">Age</label>
                <input class="formInput" type="number" min="18" max="99" name="age" v-model="form.age"
                    placeholder="Age...">
            </div>
            <div class="grid-4">
                <label class="label" for="dni">DNI</label>
                <input class="formInput" type="text" name="dni" v-model="form.dni" maxlength="9" placeholder="DNI...">
            </div>
            <div class="grid-4">
                <label class="label" for="email">Email</label>
                <input class="formInput" type="email" name="email" v-model="form.email" maxlength="24"
                    placeholder="Email...">
            </div>
            <div class="grid-4">
                <label class="label" for="car">Cars</label>
                <v-select name="car" placeholder="Select car..." :options="options"></v-select>
            </div>
            <button @click="this.person!='' ? update(this.person.id) : store() "
                class="w-full bg-blue-400 hover:bg-blue-600 transition duration-500 ease-in-out text-white p-3 rounded"
                type="submit">{{this.person!=''? 'Update' :'Create'}}</button>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'PeopleForm',
        props: ['person'],
        data: function () {
            return {
                 form: {
                   name: this.person!=''? this.person.name : '',
                   lastname: this.person!=''? this.person.lastname :'',
                   age: this.person!=''? this.person.age:'',
                   dni: this.person!=''? this.person.dni:'',
                   email: this.person!=''? this.person.email:'',
                   id_car: 1,
                },
                errors: null,
                options: [
                    'foo',
                    'bar',
                    'baz'
                ]
            }
        },
        methods: {
            store: function () {
                axios.post("/people", this.form)
                    .then(() => {
                        this.$swal({
                            title: "People created",
                            icon: 'success',
                            toast: true,
                            showConfirmButton: false,
                            position: 'top-end',
                            timerProgressBar: true,
                            timer: 5000
                        })
                        this.form.splice(0);
                    }).catch((e) => {
                        if (e.response.data.message == "Error") {
                            this.$swal({
                                title: "Email or DNI already exist",
                                icon: 'error',
                                toast: true,
                                showConfirmButton: false,
                                position: 'top-end',
                                timerProgressBar: true,
                                timer: 5000
                            })
                        }
                        this.errors = e.response.data.errors;
                    });
            },
            update: function (id) {
                console.log(this.form);
                axios.patch("/people/"   id, this.form)
                    .then(() => {
                        axios.get('/people')
                    }).catch((e) => {
                        if (e.response.data.message == "Error") {
                            this.$swal({
                                title: "Email or DNI already exist",
                                icon: 'error',
                                toast: true,
                                showConfirmButton: false,
                                position: 'top-end',
                                timerProgressBar: true,
                                timer: 5000
                            })
                        }
                        this.errors = e.response.data.errors;
                    });
            }
        }
    }

</script>

First error: When i load component in create route returns.

TypeError: Cannot read properties of null (reading 'name')"

Second error: When i click update in update component returns.

TypeError: Cannot read properties of null (reading 'person')"

I´m new with vue and i don't know exactly how can fix some basic problems. So, somebody can help?

CodePudding user response:

You can live data empty and in mounted hook check if it is for updating or adding:

data () {
  return {
    form: {
       name: '',
       lastname: '',
       age: '',
       dni: '',
       email: '',
       id_car: null,
    },
    editing: false
  }
}
mounted() {
  if(this.person) {
    this.form = this.person
    this.editing = true
  }
}

In template you can show corresponding button and trigger corresponding event:

<button v-if="editing" @click="update(person.id)"
   class="w-full bg-blue-400 hover:bg-blue-600 transition duration-500 ease-in-out text-white p-3 rounded"
   type="submit">
  Update
</button>
<button v-else" @click="store()"
   class="w-full bg-blue-400 hover:bg-blue-600 transition duration-500 ease-in-out text-white p-3 rounded"
   type="submit">
  Create
</button>
  • Related