# Creating the Contact Edit Page | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)

**Author:** Ndianabasi Udonkang  
**Published:** 2021-09-23

In this lesson, we will design the contact edit page for editing the details/properties of each contact in our Google Contacts Clone App.

---

## Tags

- [Nodejs](/llms/technical-blog/tag/nodejs.md)
- [Vuejs](/llms/technical-blog/tag/vuejs.md)
- [Adonisjs](/llms/technical-blog/tag/adonisjs.md)
- [Quasar Framework](/llms/technical-blog/tag/quasar-framework.md)

## Part of Series: [Full-Stack Google Contacts Clone with Node.js (Adonisjs Framework) and Vue.js (Quasar Framework)](/llms/technical-blog/series/clnwu9bc991hiu3wo2vwmw45/full-stack-google-contacts-clone-with-node-js-adonisjs-framework-and-vue-js-quasar-framework.md)

This article is part of the **[Full-Stack Google Contacts Clone with Node.js (Adonisjs Framework) and Vue.js (Quasar Framework)](/llms/technical-blog/series/clnwu9bc991hiu3wo2vwmw45/full-stack-google-contacts-clone-with-node-js-adonisjs-framework-and-vue-js-quasar-framework.md)** series.

### Articles in this Series:

- [Introduction to Full-Stack Google Contacts Clone with Node.js (Adonisjs Framework) and Vuejs (Quasar Framework)](/llms/technical-blog/article/xe5mlxg43s9rpx1pxsvfdp3r/introduction-to-full-stack-google-contacts-clone-with-node-js-adonisjs-framework-and-vuejs-quasar-framework.md)
- [Workspace Setup | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/fo8str8yjpkz5dygxg875bpw/workspace-setup-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Frontend Overview | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/nxgmng6fhf1cwjk30coflro2/frontend-overview-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [The Left Drawer | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/m6fagvy2il5h65llxxbbl9os/the-left-drawer-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Improve The Header | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/jjwbxcg450jmkkcrrmkmwvwj/improve-the-header-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [New Contact Form Design | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/ebguwpkntk3empakunrki4dq/new-contact-form-design-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Validating the Contact Form with Vuelidate | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/z0xr9m2ljler2cwnpsw2ycwa/validating-the-contact-form-with-vuelidate-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Designing the Contacts Table | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/h2p1x1z406ib38zu2dci3jur/designing-the-contacts-table-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Designing the Contacts Table (Part 2) | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/j0iscua9gg8ekuz8ifh6chpn/designing-the-contacts-table-part-2-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Refactoring the Main Layout | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/uktmlqsivwtr3cvnpld59k9q/refactoring-the-main-layout-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Improving User Experience with the Contacts Table | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/dzs812auf61ej7qu2cg726dh/improving-user-experience-with-the-contacts-table-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- [Designing the Contact Details Page | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)](/llms/technical-blog/article/kf9pz97n63fvgfrcy5viwzrg/designing-the-contact-details-page-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js.md)
- **Creating the Contact Edit Page | Full-Stack Google Contacts Clone with Adonis.js/Node.js and Quasar (Vue.js)** (Current Article)
- [How Software Backends Work | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/aca8fcrghz70nn1wqg3uzbum/how-software-backends-work-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Setting Up The Backend | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/fxb49fmz9ljbwrimbnnzudfv/setting-up-the-backend-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Why Choose the AdonisJs Framework? | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/lnhm5oudx34yo2869gmcms37/why-choose-the-adonis-js-framework-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Setting Up Our API Server with AdonisJs Framework | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/x1jgmet84aqj9qggu5mulkh0/setting-up-our-api-server-with-adonis-js-framework-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Setting Up Postman with the API Server | Full-Stack Google Contacts Clone with AdonisJS (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/v4qehksislosmuy92qgjr4ct/setting-up-postman-with-the-api-server-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [The Model-View-Controller Design Pattern in AdonisJS | Full-Stack Google Contacts Clone with AdonisJS (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/h5wqql65iejop5xrplujw458/the-model-view-controller-design-pattern-in-adonis-js-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Create Column Definitions & Insert New Contacts | Full-Stack Google Contacts Clone with AdonisJS (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/asc2emsho4u73r6jb2gxjddw/create-column-definitions-and-insert-new-contacts-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Data Validation & Sanitisation with AdonisJS | Full-Stack Google Contacts Clone with AdonisJS (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/bcey0ac7m5sbs9hqy1h824sl/data-validation-and-sanitisation-with-adonis-js-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Creating a Middleware and Updating a Contact | Full-Stack Google Contacts Clone with AdonisJS (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/oqxzmtgfy1r3oewpnedc7wf6/creating-a-middleware-and-updating-a-contact-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-framework-vue-js.md)
- [Fetching and Deleting a Contact with AdonisJS | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/p6bh0ponq43u3vi6o8uww84x/fetching-and-deleting-a-contact-with-adonis-js-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Using Model Factories and Seeders in AdonisJS | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/cfotveuxbgjtdp12l6pzcb2y/using-model-factories-and-seeders-in-adonis-js-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Creating and Registering a Vuex Module | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/cw96ewnzujgsz2e2garhbuzb/creating-and-registering-a-vuex-module-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Connecting UI Components to the Vuex Store | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/fdyqp17yehbnqrjvjvab4b5b/connecting-ui-components-to-the-vuex-store-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Connecting the Frontend to the API Server | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/fk4262359gg3g7f0jn95fn9b/connecting-the-frontend-to-the-api-server-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Creating and Updating Contacts From the Frontend | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)](/llms/technical-blog/article/t15w2s3ao9jo74l96stjo7z6/creating-and-updating-contacts-from-the-frontend-full-stack-google-contacts-clone-with-adonis-js-framework-node-js-and-quasar-framework-vue-js.md)
- [Uploading Files and Creating Avatars for Contacts With AdonisJS and Axios](/llms/technical-blog/article/hg9ilaubqesm8angg0rhrjp9/uploading-files-and-creating-avatars-for-contacts-with-adonis-js-and-axios.md)
- [Deleting a Contact with AdonisJS and Vuejs](/llms/technical-blog/article/zdr4pxmgcax2dsfnwimhty0g/deleting-a-contact-with-adonis-js-and-vuejs.md)

---

## Article Content

In this lesson, we will design the contact edit page for editing the details/properties of each contact in our Google Contacts Clone App. We will begin by adding a new `edit_contact` route to our application and then adding an `click` event listener to the edit button on each row of our Contacts table so that when users click on the `Edit` button, they will be taken to the Edit page for that contact. We will also add a router navigation (`to`) prop to the `Edit` button on our contact view page, so that users can quickly edit a contact while viewing it.

Let's start by creating a new branch for our repo:

```bash
# Make sure you are within your project
git checkout -b 09-creating-the-contact-edit-page
```

The video below shows what we will achieve in this lesson:

%\[https://vimeo.com/612451069]

### Setup

Let's make some few changes to other files before we create the Contact Edit page

#### 1. Add a Pointer Cursor to the Toolbar Title of the Header

Open `ui/src/layouts/MainLayout.vue`. At Line 33, add the following:

```diff
            <span
              :class="[
                $q.screen.gt.xs && 'q-ml-sm',
                $q.screen.lt.xs && 'hidden',
              ]"
+              style="cursor: pointer"
              >Contacts
           </span>
```

Refer to [this snapshot](https://github.com/ndianabasi/google-contacts/blob/908fa58d27a30195c4bce7b4d3e71327114b021e/ui/src/layouts/MainLayout.vue#L33).

At Line 228, we add a `back` button to the default title toolbar above our pages:

```html
        <q-btn
          color="primary"
          flat
          round
          icon="arrow_back"
          @click.prevent="$router.go(-1)"
        />
```

Refer to [these lines](https://github.com/ndianabasi/google-contacts/blob/908fa58d27a30195c4bce7b4d3e71327114b021e/ui/src/layouts/MainLayout.vue#L228-L234) in our snapshot.

#### 2. Improve our Types

Open `ui/src/types/index.ts`. And make the following changes:

```diff
export interface FormItem {
  label: string;
  required: boolean;
-  value: string;
+  value: string | number | null | undefined;
  inputType?: "text" | "number" | "date" | "email" | "url" | "textarea";
  icon?: string;
  autocomplete?:
...
- export interface Contact {
+ export interface Contact
+   extends Record<string, string | null | undefined | number> {
    id: string;
    firstName: string;

```

Refer to [here](https://github.com/ndianabasi/google-contacts/blob/908fa58d27a30195c4bce7b4d3e71327114b021e/ui/src/types/index.ts#L5) and [here](https://github.com/ndianabasi/google-contacts/blob/908fa58d27a30195c4bce7b4d3e71327114b021e/ui/src/types/index.ts#L31-L32) in the snapshot.

#### 3. Add the `edit_contact` route

Open `ui/src/router/routes.ts`; add the following below the route object for `view_contact` route.

```ts
{
        path: "contacts/:contactId/edit",
        name: "edit_contact",
        component: () => import("pages/contacts/EditContact.vue"),
        meta: { title: "Edit Contact", showDefaultTitle: true },
        props: true,
}
```

Refer to [this lines in the snapshot](https://github.com/ndianabasi/google-contacts/blob/908fa58d27a30195c4bce7b4d3e71327114b021e/ui/src/router/routes.ts#L27-L33) for the file. Here, we've added a new route with name: `edit_contact`. The `edit_contact` route has a single route parameter named: `contactId`. We set `showDefaultTitle` as `true` within the `meta` object so that the top title toolbar above the page is rendered. We also set `props` to `true` so that the route parameters will be injected to the route component: `pages/contacts/EditContact.vue`.

If you are following me step-by-step, you might have an error because the route component (`pages/contacts/EditContact.vue`) has not be created yet.

#### 4. Make the `Edit` button on our Contacts table rows functional

Open `ui/src/pages/Index.vue`. Make the following changes:

1. At Line 57, change: `@click.stop.prevent` to `@click.prevent`
2. At Line 105, change `<q-btn flat round color="primary" icon="edit" />` to:

   ```ts
                <q-btn
                  flat
                  round
                  color="primary"
                  icon="edit"
                  @click.stop.prevent="
                    $router.push({
                      name: 'edit_contact',
                      params: { contactId: props.row.id },
                    })
                  "
                />
   ```

````

This adds a `click` event listener which navigates to the newly-added `edit_contact` route with `props.row.id` as the value of the `contactId` route parameter. The event modifier `click.stop` ensures that the `click` event does not propagate to the `q-tr` component where we have an event listener which pushes to the Contact details page. So the `click` event on this `q-btn` component will be handled at this level and stopped. `click.prevent` modifier prevents the default behaviours of buttons which reloads the entire page when clicked.

#### 5. Make the `Edit` button on our Contact Details Page functional

Open `ui/src/pages/contacts/ViewContact.vue` and add the following:

1. At Line 73, change `<q-btn color="primary">Edit</q-btn>` to:

   ```html
            <q-btn
              :to="{
                name: 'edit_contact',
                params: { contactId: $route.params.contactId },
              }"
              color="primary"
              >Edit</q-btn
            >
````

Here, we have made the `Edit` button on the top-right side (desktop screen) of our Contact Details page functional.

2. At Line 171, change `<q-btn round flat icon="outbound"></q-btn>` to:

   ```html
                      <q-btn
                          :to="{
                            name: 'edit_contact',
                            params: { contactId: $route.params.contactId },
                          }"
                          round
                          flat
                          icon="outbound"
                        >
                     </q-btn>
   ```

````

   Here, we make the `Edit` button in our bottom right sticky (in mobile responsive screens) functional.


### Creating the Contact Edit Page

From my experience, my recommended approach to working with creation and edit forms is to either derive the creation form from the edit form (if the edit form was designed first) or derive the edit form from the creation form (if the creation form was designed first).

It is total waste of time to design to separate forms for creation and edit of entities because they will have very similar JavaScript logic and HTML markup. So, why repeat yourself completely. Don't forget the DRY (Don't Repeat Yourself) principle in software development.

As a result, we will derive the Contact Edit page/form from the Contact Creation page/form.

#### Create the `Contact Edit` component

```bash
# With VS code
code ui/src/pages/contacts/EditContact.vue # Opens the `EditContact.vue` file
### CTRL+S to save for the first time.

# With other code editors
touch ui/src/pages/contacts/EditContact.vue # Creates the `EditContact.vue` file
# Open by searching with CTRL+P or opening from the file browser
````

Copy [all the contents of this snapshot](https://github.com/ndianabasi/google-contacts/blob/09-creating-the-contact-edit-page/ui/src/pages/contacts/EditContact.vue) into the created `EditContact.vue` file. The content is also shown below:

```html

<template>
  <CreateContact :contact-id="contactId" edit-mode />
</template>

<script lang="ts">
import { defineComponent, PropType } from "vue";
import CreateContact from "./CreateContact.vue";
export default defineComponent({
  name: "EditContact",
  components: { CreateContact },
  props: {
    contactId: {
      type: String as PropType<string>,
      required: true,
      default: "",
    },
  },
  setup() {
    //
  },
});
</script>
```

The component has one prop, the `contactId` prop. Remember that this prop is injected from `Vue Router` because we set `props` to `true` in our route definition object.

To derive the Contact Edit page from the Contact Creation page, we do the following:

1. In the `script` section and at Line 7, we import the `CreateContact.vue` file which is our Contact Creation page/form into our `EditContact.vue` file.

2. At Line 11, we add it to our `components` objects so that it is available for use in our `EditContact.vue` component.

3. At Line 2 (within the `template` section), we add the `CreateContact` component into our markup, thereby consuming and rendering it.

The `CreateContact` component needs to props: `contactId` and `editMode`. We set the `contactId` prop for `CreateContact` to the value of `contactId` prop (coming from `Vue Router`. The `editMode` prop is set to `true` with the attribute `edit-mode` on the `CreateContact` component.

Now, we will make the rest of the changes in the `ui/src/pages/contacts/CreateContact.vue` file.

Open `ui/src/pages/contacts/CreateContact.vue`. Refer [to this snapshot file](https://github.com/ndianabasi/google-contacts/blob/09-creating-the-contact-edit-page/ui/src/pages/contacts/CreateContact.vue) for the updates.

1. Add `  PropType`, `watchEffect`, and `onBeforeUnmount` to the imports from `"vue"` at Line 56.

   ```ts
   ```

import {
defineComponent,
reactive,
computed,
PropType,
watchEffect,
onBeforeUnmount,
} from "vue";

````

2. Add `Contact` to the imports from `"../../types"` at Line 67.

   ```ts
import { FormInterface, Contact } from "../../types";
````

3. Import `contacts` from `"../../data/Google_Contacts_Clone_Mock_Data"` at Line 69.

   ```ts
   ```

import { contacts } from "../../data/Google\_Contacts\_Clone\_Mock\_Data";

````

4. Update the `regex` validator at Line 73 to:

   ```ts
const phoneNumberValidator = helpers.regex(
  /^[+]?[(]{0,1}[0-9]{1,4}[)]?[\(\)-\s\./0-9]*$/
);
````

5. Remove the component object:`components: {},` at Line 66.

6. Add the two props from Line 78:

   ```ts
   ```

props: {
editMode: {
type: Boolean as PropType<boolean>,
required: true,
default: () => false,
},
contactId: {
type: String as PropType<string>,
required: false,
default: "",
},
},

````

7. Change `setup() {` to `setup(props) {` at Line 90. We need to pass in the props into the setup function.

8. From Line 270, add the following:

   ```ts
    let contact: Contact = reactive({
      id: "",
      firstName: "",
      surname: "",
      email1: "",
      phoneNumber1: "",
    });
    const stopContactsEffect = watchEffect(
      () => {
        if (!props.contactId || !props.editMode) return;
        const fetchedContact = contacts.filter(
          (cont) => cont.id === props.contactId
        );
        const [fetchedContactObject] = fetchedContact;
        contact = fetchedContactObject;
        Object.keys(contact).forEach((key) => {
          if (key !== "id") {
            form[key].value = contact[key];
          }
        });
      },
      { flush: "pre" }
    );
    const submitPayload = computed(() => {
      const payload = {};
      Object.keys(form).forEach((key) => {
        Object.defineProperty(payload, key, {
          value: form?.[key]?.value,
          writable: false,
        });
      });
      return payload;
    });
````

Here, we introduce a similar `watchEffect` hook we used in the previous lesson. [See this section](https://tech.ndianabasi.com/designing-the-contact-details-page-or-full-stack-google-contacts-clone-with-adonisjsnodejs-and-quasar-vuejs#the-script-section). After computing `contact` within the `watchEffect` hook, we initialise the form fields with the lines:

```ts
     Object.keys(contact).forEach((key) => {
       if (key !== "id") {
         form[key].value = contact[key];
       }
     });
```

Here, we derived an array from the keys of our `contact` object using `Object.keys(contact)`. Then, we loop through each key of the array. If the `key` is not named `id`, we set the form with the value of the key within `contact`.  This is a clean and efficient way of doing the following:

```ts
form.firstName.value = contact.firstName;
form.surname.value = contact.surname;
form.email1.value = contact.email1
...
```

Then from Line 297, we compute a simple `submitPayload` from our `form` object. Here, we loop through the keys of the `form` variable. For each key, we set that key as the property of the `payload` object using the `Object.defineProperty()` method. The method takes a `propertyDescriptor` object as the third parameter. Within the `propertyDescriptor`, we set the value and declare that the value is not writable going forward. This finalises the value for submission to the server. At the end, we return the `payload` object.

```ts
const submitPayload = computed(() => {
   const payload = {};
   Object.keys(form).forEach((key) => {
     Object.defineProperty(payload, key, {
       value: form?.[key]?.value,
       writable: false,
     });
   });
   return payload;
 });
```

```
This is the same thing as doing:
```

```ts
const submitPayload = {}
submitPayload.firstName = form.firstName.value
submitPayload.surname = form.surname.value
submitPayload.email1 = form.email1.value
...
```

You will agree that the former is cleaner though the latter is simpler to understand for learners. That's why, I'm taking time to explain both versions.

9. At Line 321, we add a `console` statement to `submitPayload.value` when the form has not errors.
   ```ts
        console.log(submitPayload.value);
   ```

````

10. At Line 324, we modify the message for the `$q.notify()` function:

   ```ts
        $q.notify({
          message: props.editMode ? "Contact edited" : "Contact created",
          type: "positive",
        });
````

11. At Line 330, we stop the `watchEffect` hook with a call to the `onBeforeUnmount` hook.

```ts
 onBeforeUnmount(() => {
   void stopContactsEffect();
 });
```

12. Lastly and within the `template` section, we improve the responsiveness of our `submit` button. At Line 38, we update `div` to a `flex` row, and introduce a responsive column to wrap thte `q-btn` component.

```html
     <div class="q-mt-xl row justify-center">
       <div class="col-12 col-md-6 col-lg-6 col-xl-6">
         <q-btn
           class="full-width"
           label="Submit"
           type="submit"
           color="primary"
           @click.prevent="submitForm"
         />
       </div>
```

Take sometime, to fill and submit the form while check the `console` of the dev tool. Also inspect the relationship between the `CreateContact` and `EditContact` components with the Vue devtool. Also navigate to the Contact Edit page from the Contacts table and also from the Contact Details page.

This concludes our discussions for this lesson.

Save all your files, commit and merge with the master branch.

```bash
git add .
git commit -m "feat(ui): complete design of the contact edit page"
git push origin 09-creating-the-contact-edit-page
git checkout master
git merge master 09-creating-the-contact-edit-page
git push origin master
```

In the next lesson, we will begin discussions on the backend of our app by talking about how backend for software (applications) works. See you there.


*This document was generated from the live article page on https://ndianabasi.com/technical-blog/article/fmr90prj84c9zn0633jc368g/creating-the-contact-edit-page-full-stack-google-contacts-clone-with-adonis-js-node-js-and-quasar-vue-js • 2026-06-07*
