Image

build-a-gmail-clone-with-vue-3

4 min read
Last update: December 19, 2021

Axios & JSON Server

For the starting code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-4-start

The last lesson was all about getting our app ready to handle asynchronous code using the Suspense component and an async setup function. This lesson will use that in order to pull code asynchronously from the server, then save updated data back to the server.

First, let’s set up our server. If you’re following along with the starter code, then run the following commands in your CLI, while in the root directory of this project:

npm install -g json-server
json-server --watch db.json

We’re using a file called db.json, included in the starter code, to create a simple REST server.

If you don’t have the file yet, you can create it and paste in the code below:

{
"emails": [
{
"id": 1,
"from": "team@vuemastery.com",
"subject": "What's up with Vue 3.0? Here's how to find out from Evan You",
"body": "The opening keynote of VueConf US this year was Evan You (the creator of Vue), giving his State of the Vuenion address. He walked us through the journey of getting Vue 3 from a prototype to a reality the past year. He also dove into Vue's overall growth in the community.",
"sentAt": "2020-03-27T18:25:43.511Z",
"archived": false,
"read": false
},
{
"id": 2,
"from": "jeffrey@vuetraining.net",
"subject": "Learn by doing - Vue 3 Zero to Intermediate in 8 weeks",
"body": "Building projects is one of the most effective ways to learn - and _the_ most effective way _remember_ what you've learned - but it can be frustrating.\n\nThis 8-week course takes the pain out of 'learning by doing'.\n\nEach week we give you\n\n* a project that will grow your skills without overwhelming you\n* links to hand-picked resources, such as Vue Mastery videos, that share the knowledge you'll need for the project (no more useless rabbit holes)\n* answers to any and all questions you have while working\n* feedback on your completed code (so you're only learning good habits)\n\nOur instructors are standing by to answer your questions.\n\nReady to learn?",
"sentAt": "2020-05-20T18:25:43.511Z",
"archived": false,
"read": false
},
{
"id": 3,
"from": "damian@dulisz.com",
"subject": "#177: Updated Vue.js Roadmap; Vuex v4.0.0-alpha.1 has been released; Kia King Ishii join the core team; Nuxt v2.12 released; Videos from Vue.js Amsterdam 2020 are here!",
"body": "First of all, lets congratulate Kia King Ishii on joining the Vue.js core team! 🎉 He has been doing an incredible job building vuex-orm and will now focus on working on the next versions of Vuex.\n\nSpeaking of which – Vuex v4.0.0-alpha.1 has just been released! This is the version of Vuex that will work with Vue 3.0 but keep the familiar API you know from the current version.",
"sentAt": "2020-03-18T18:25:43.511Z",
"archived": false,
"read": true
},
{
"id": 4,
"from": "anthony@vuejsdevelopers.com",
"subject": "'Vue 3 Release Roadmap' + 6 more must-read articles from this week",
"body": "Newsletter Issue #161",
"sentAt": "2020-03-24T18:25:43.511Z",
"archived": true,
"read": true
}
]
}

Visit [http://localhost:3000/emails](http://localhost:3000/emails) to see the result. It’s a REST Index of the emails.

Now let’s use that endpoint in our code.

import axios from 'axios';

export default {
async setup(){
let response = await axios.get('http://localhost:3000/emails');
let emails = response.data;
return {
format,
emails
}
},
}

It works just as well as when we were loading the data directly.

You can use ES6 destructuring to make the code a bit shorter.

import axios from 'axios';

export default {
async setup(){
let {data: emails} = await axios.get('http://localhost:3000/emails');
return {
format,
emails
}
},
}

There’s more we can do, now that we’re storing our data in a file… now, instead of resetting everything when you reload, we can actually save the changes we make.

Let’s start with reading the emails…

<tr v-for="email in unarchivedEmails" :key="email.id" :class="[email.read ? 'read': '', 'clickable']" @click="readEmail(email)">
methods: {
readEmail(email){
email.read = true
axios.put(`http://localhost:3000/emails/${email.id}`, email)
}
}

Click an email to read it, then reload, then you’ll see that it’s been saved!

Look at your db.json and see that it’s changed to reflect the newly read email.

Now let’s do that with the archive action:

<td><button @click="archiveEmail(email)">Archive</button></td>
archiveEmail(email){
email.archived = true;
axios.put(`http://localhost:3000/emails/${email.id}`, email)
}

Finally, let’s put our PUT request in a new function, which we call from readEmail and openEmail, so that if we need to change how the email is updated, we only need to do it in one place.

methods: {
readEmail(email) {
email.read = true
this.updateEmail(email)
},
archiveEmail(email) {
email.archived = true
this.updateEmail(email)
},
updateEmail(email) {
axios.put(`http://localhost:3000/emails/${email.id}`, email)
}
}

For the ending code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-4-end

Jeffrey teaches an 8-week beginning Vue course with guaranteed results. Built on top of the VueMastery curriculum, with extra hands-on assignments and personal attention. You can find it here.