We are still missing the create and update components and in this article, we are going to implement these missing parts. With this post, we are going to finalize our application development process.
For the complete series navigation visit: Vue.js Series.
To download the source code for this part, visit Create and Update Owner Entity Source Code.
This post is divided into several sections:
Creating Owner Entity
We are going to create a form that has three input fields: name, date of birth and address. As soon as the user fills up the data and submits the form, we are going to send a POST request to the server. After receiving a response, a modal will show up and display if we successfully created the Owner entity or not.
To make things easier to read and understand we are going to write this component in several segments. Let’s start with a template.
The OwnerCreate Template
First, we are going to create a form with three input fields. To do that, let’s create the OwnerCreate.vue
component in the src/components/Owner
folder:
<template> <b-container fluid> <div class="form-wrapper"> <b-form @submit.prevent="createOwner"> <b-form-group :label-cols="2" breakpoint="md" horizontal label="Name of the owner:" for="name"> <b-col :md="5"> <b-input id="name" v-model="formData.name" maxlength="60" required /> </b-col> </b-form-group> <b-form-group :label-cols="2" breakpoint="md" horizontal label="Date of birth:" for="dateOfBirth"> <b-col :md="5"> <b-input id="dateOfBirth" v-model="formData.dateOfBirth" type="date" required /> </b-col> </b-form-group> <b-form-group :label-cols="2" breakpoint="md" horizontal label="Address:" for="Address"> <b-col :md="5"> <b-input id="Address" v-model="formData.address" maxlength="100" required /> </b-col> </b-form-group> </b-form> </div> </b-container> </template>
In this template, we have two new features. On the form tag, there is a new statement
@submit.prevent
. We have learned in part 5 that @submit
is the syntax to listen on the submit
event. But now we have the .prevent
modifier which is equivalent to the vanilla JavaScript expression event.preventDefault()
. So, we are preventing the native browser behavior to redirect to the form’s action because we want to send data with Axios.Another new feature is v-model
and we are going to explain that a bit later on.
Under the form tag, we are going to create the Save
and Cancel
buttons. The first will submit the form and the second will redirect to the OwnerList
route.
So, right below the last b-form-group
tag we are going to insert this piece of code:
<br ><br > <b-col :md="5" offset="4"> <b-button type="submit" variant="info">Save</b-button> <b-button :to="{ name: 'OwnerList' }" variant="danger">Cancel</b-button> </b-col>
Furthermore, we are going to create a modal to show an information whether or not our action was successful. We are going to put that modal before the closing
b-container
tag:<b-modal ref="alertModal" :title="alertModalTitle" :ok-only="true" @ok="onAlertModalOkClick"> <p class="my-4">{{ alertModalContent }}</p> </b-modal>
As a continuation, we are going to add some styles:
<style> .form-wrapper { margin-top: 20px; min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; box-shadow: inset 0 1px 1px rgba(0,0,0,.05); } </style>
Now, let’s implement the logic behind this template.
OwnerCreate Script
We need to create variables that will store the data from our inputs. What we need more is to create variables for a modal title and modal body. To do that, we are going to create one more variable isSuccessfully
to show the correct message whether our POST request was successful or not.
It’s time to explain the v-model
directive and how we use it to bind these variables with inputs.
It’s like the data binding expression (:prop=”value”
) that we have seen in the previous parts but this one is a two-way binding. In the previous parts, we have only passed the data from the parent component to the child component using the :prop=”value”
syntax and if a child component tries to modify that value, the warning will appear because that’s not allowed. By using the v-model
directive, both parent and child component can modify that value and both components will be notified about that modification.
Let’s implement that:
<script> export default { name: 'OwnerCreate', data() { return { formData: { name: '', dateOfBirth: '', address: '' }, alertModalTitle: '', alertModalContent: '', isSuccessfully: false }; }, }; </script>
Now, let’s implement the
createOwner
method which sends a POST request and the ‘formData’ object to the server. Depending on the server’s response, the isSuccessfully
variable will be set to true or false. If the create action is successful, the modal will show up and the formData
object will be cleaned up. If any problem occur, the modal will display an error message.Let’s implement that method:
methods: { createOwner() { OwnerService.create(this.formData).then(() => { this.isSuccessfully = true; this.alertModalTitle = 'Successfully'; this.alertModalContent = 'Successfully created Account Owner'; this.$refs.alertModal.show(); this.formData = { name: '', dateOfBirth: '', address: '' }; }).catch((error) => { this.isSuccessfully = false; this.alertModalTitle = 'Error'; this.alertModalContent = error.response.data; this.$refs.alertModal.show(); }); } }
We also need to import the
OwnerService
reference:import OwnerService from '@/api-services/owner.service';
When modal shows up, we need to click on the
OK
button. That click will trigger the onAlertModalOkClick
method which will redirect a user to the OwnerList
route if the response was successful.We are going to edit the OwnerCreate.vue
component one more time to implement that method:
onAlertModalOkClick() { if (this.isSuccessfully) { this.$router.push({ name: 'OwnerList' }); } }
We still need to make a route and a way to go to this component.
Navigating to the OwnerCreate component
Let’s edit the src/router/index.js
file:
{ path: '/owner/list', name: 'OwnerList', component: OwnerList }, { path: '/owner/create', name: 'OwnerCreate', component: OwnerCreate }, { path: '/owner/:id', name: 'OwnerDetails', component: OwnerDetails },
It is important to place our route above the
OwnerDetails
route. If we place it below, then when we access the /owner/create
route the OwnerDetails
route will be triggered because create
part of the route will be recognized as the :id
parameter.And finally, let’s modify the src/components/Owner/OwnerList.vue
component:
<template> <div> <b-row> <b-col md="2" offset-md="10"> <router-link :to="{ name: 'OwnerCreate' }">Create owner</router-link> </b-col> </b-row> ....
The
<router-link>
tag will create an <a>
tag but will not initiate redirection process when clicked, it will only trigger vue-router to switch a route.Great!
Now, let’s start a terminal and type the npm run dev
command to check if everything is OK:
When we enter valid data and click on the Save
button:
Editing Owner Entity
The edit form is almost identical as the create form. There are only a few differences. We have the :id
parameter in a route and we have to fetch the data for that owner from the backend and display it on the form. Once we click on the Save
button, we are going to send the PUT request to the backend with the new data for that Owner.
Let’s create the new OwnerUpdate.vue
component inside the src/components/Owner
directory. The only difference between this template and the one for creating the owner is the name of the event handler for the submit form. That being the case let’s just copy the template from the OwnerCreate.vue
and paste it inside a new component and edit the name of the event handler:
<template> <b-container fluid> <div class="form-wrapper"> <b-form @submit.prevent="updateOwner"> <b-form-group :label-cols="2" breakpoint="md" ... </template>
In the script part, we have the same data as in the previous component. Moreover, the event handler for the modal’s
ok
button is the same. We are going to implement the logic for fetching owner in the created lifecycle hook and for the updateOwner
method.So, let’s implement the script part of the OwnerUpdate.vue
file:
<script> import OwnerService from '@/api-services/owner.service'; export default { name: 'OwnerUpdate', data() { return { formData: { name: '', dateOfBirth: '', address: '' }, alertModalTitle: '', alertModalContent: '', isSuccessfully: false }; }, created() { OwnerService.get(this.$router.currentRoute.params.id).then((response) => { this.formData.name = response.data.name; this.formData.dateOfBirth = response.data.dateOfBirth.split('T')[0]; this.formData.address = response.data.address; }); }, methods: { updateOwner() { OwnerService.update(this.$router.currentRoute.params.id, this.formData).then(() => { this.isSuccessfully = true; this.alertModalTitle = 'Successfully'; this.alertModalContent = 'Successfully updated Account Owner'; this.$refs.alertModal.show(); }).catch((error) => { this.isSuccessfully = false; this.alertModalTitle = 'Error'; this.alertModalContent = error.response.data; this.$refs.alertModal.show(); }); }, onAlertModalOkClick() { if (this.isSuccessfully) { this.$router.push({ name: 'OwnerList' }); } } } }; </script>
Let’s also define the route for this component:
{ path: '/owner/create', name: 'OwnerCreate', component: OwnerCreate }, { path: '/owner/update/:id', name: 'OwnerUpdate', component: OwnerUpdate }, { path: '/owner/:id', name: 'OwnerDetails', component: OwnerDetails },
And finally, we need to direct a user to this page when a user clicks on the
Update
button on the OwnerList
component:updateOwner(ownerId) { this.$router.push({ name: 'OwnerUpdate', params: { id: ownerId } }); },
Let’s again type
npm run dev
command in a terminal and see results:When we click the Update
button on the OwnerList component, we will be directed to a new component and the form will be populated with the actual data:
Let’s try to modify our input fields and click on the Save
button. The modal will appear:
And we will have updated Owner entity on the OwnerList component.
Conclusion
We have finished our Vue.js journey. Now we have a fully functional application that is ready for deployment. Vue.js has many other great features, which we haven’t covered in this series, but we have learned a lot from this series as well.
By reading this post you have learned:
- How two-way binding works
- How to prevent the default behavior of events
- The way to handle POST request
- The way to handle PUT request