Our Tweetr app will have a settings section with links for users to edit their profile and change their password. In this lesson, we'll start by allowing users to edit their profile.

We'll start by creating the settings menu (that is the links). Within the components folder, create a User folder, and then within the User folder, create a Settings folder. Create a UserSettingsMenu.vue file inside the Settings folder and paste the code below into it:

// src/components/User/Settings/UserSettingsMenu.vue

<template>
    <div class="four wide column">
        <router-link class="ui button mini primary" to="/">Back Home</router-link>
        <div class="ui fluid vertical pointing menu">
            <div class="item">
                <router-link to="/settings/profile">Profile</router-link>
            </div>
            <div class="item">
                <router-link to="/settings/password">Password</router-link>
            </div>
        </div>
    </div>
</template>

Just a couple of links to go to the homepage, edit the user profile page, and change password page, respectively.

Table of Contents

    Next, we'll create the component that will allow users to edit their profile. Within the Settings folder, create UserProfileSettings.vue and paste the code below into it:

    // src/components/User/Settings/UserProfileSettings.vue
    
    <template>
      <div class="ui stackable grid container">
        <UserSettingsMenu/>
    
        <div class="eight wide column">
          <div class="ui segment">
            <h2 class="ui dividing header">Edit Profile</h2>
    
            <Notification
              :message="notification.message"
              :type="notification.type"
              v-if="notification.message"
            />
    
            <form class="ui form" @submit.prevent="updateProfile">
              <div class="field" :class="{ error: errors.has('name') }">
                <label>Full Name</label>
                <input type="text" name="name" v-model="name" v-validate="'required'">
                <span v-show="errors.has('name')" class="is-danger">{{ errors.first('name') }}</span>
              </div>
    
              <div class="field" :class="{ error: errors.has('name') }">
                <label>Username</label>
                <input type="text" name="username" v-model="username" v-validate="'required'">
                <span v-show="errors.has('username')" class="is-danger">{{ errors.first('username') }}</span>
              </div>
    
              <div class="field" :class="{ error: errors.has('email') }">
                <label>Email</label>
                <input type="email" name="email" v-model="email" v-validate="'required|email'" placeholder="Email">
                <span v-show="errors.has('email')" class="is-danger">{{ errors.first('email') }}</span>
              </div>
    
              <div class="field">
                <label>Bio</label>
                <textarea v-model="bio" rows="5" placeholder="A breif bio of you"></textarea>
              </div>
    
              <div class="field">
                <label>Location</label>
                <input type="text" v-model="location" placeholder="Your location">
              </div>
    
              <div class="field">
                <label>Website URL</label>
                <input type="url" v-model="websiteUrl" placeholder="Website URL">
              </div>
    
              <button class="ui button primary">Update profile</button>
            </form>
          </div>
        </div>
      </div>
    </template>

    We use the UserSettingsMenu component created earlier as well as the Notification component. We are also using the VeeValidate plugin. The form inputs will be prepopulated will the user's details gotten from our API. An updateProfile method will be called once the form is submitted.

    Next, let's add the JavaScript section to the component. Still inside UserProfileSettings.vue, add the code below just after the template section:

    // src/components/User/Settings/UserProfileSettings.vue
    
    <script>
        import Notification from '@/components/Notification'
        import UserSettingsMenu from '@/components/User/Settings/UserSettingsMenu'
    
        export default {
            name: 'UserProfileSettings',
            components: {
                Notification,
                UserSettingsMenu
            },
            data () {
                return {
                    name: '',
                    username: '',
                    email: '',
                    bio: '',
                    location: '',
                    websiteUrl: '',
                    notification: {
                        message: '',
                        type: ''
                    }
                }
            },
            beforeRouteEnter (to, from, next) {
                const token = localStorage.getItem('tweetr-token')
    
                return token ? next() : next('/login')
            },
            created () {
                this.fetchAuthenticatedUser()
            },
            methods: {
                fetchAuthenticatedUser () {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .get('account/me', {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        })
                        .then(response => {
                            this.name = response.data.data.name
                            this.username = response.data.data.username
                            this.email = response.data.data.email
                            this.location = response.data.data.location
                            this.bio = response.data.data.bio
                            this.websiteUrl = response.data.data.website_url
                        })
                },
                updateProfile () {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .put(
                            '/account/update_profile',
                            {
                                name: this.name,
                                username: this.username,
                                email: this.email,
                                location: this.location,
                                bio: this.bio,
                                website_url: this.websiteUrl
                            },
                            {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            }
                        )
                        .then(response => {
                            // display success notification
                            this.notification = Object.assign({}, this.notification, {
                              message: response.data.message,
                              type: 'success'
                            })
                        })
                }
            }
        }
    </script>

    First, we import both the Notification and UserSettingsMenu components. Then we define the user's data as well as the notification data. Using Vue router's beforeRouteEnter navigation guard, we check if there is a tweetr-token in localstorage. If present (that is, the user is logged in), we show the user the form to edit profile. If not, we redirect them to login. Because we want to prepopulate the form with the user's data, we need to first fetch this data from our API. Using the created life cycle hook, we call a fetchAuthenticatedUser method which will handle fetching the details of the authenticated user. This method makes a GET request to the /account/me endpoint on our API. Because this endpoint is restricted to only authenticated users, we have to pass the user's token along with the request. We then assign our data accordingly to those retrieved from the API.

    Next, we define the updateProfile method that handles updating user's profile. This method makes a PUT request to our API passing along the data entered by the user as well as the user's token. Finally, we display a success message returned by passing it to the Notification component.

    Adding Edit Profile Route

    Open src/router/index.js, and add the code below to it:

    // src/router/index.js
    
    import UserProfileSettings from '@/components/User/Settings/UserProfileSettings'
    
    // add these inside the `routes` array
    {
        path: '/settings/profile',
        component: UserProfileSettings
    },

    Now when we visit the /settings/profile route, we should see the edit profile form as in the image below:

    Chimezie Enyinnaya

    20 posts

    Software Developer [PHP Laravel JavaScript NodeJS AdonisJS VueJS] | movie lover | run http://openlaravel.com