Access Asynchronous Data in an Express API with async/await

Jamund Ferguson
InstructorJamund Ferguson
Share this video with your friends

Social Share Links

Send Tweet

This lesson will rely on the built-in support for async functions found in Express 5 to demonstrate how an API can easily work with data asynchronously. By the end of the lesson our API will have the ability to save its notes to disk as they're added and read them when the server starts up again.

First we'll update our Note model to persist data to the filesystem using the MapStore class created in a previous lesson. Then we'll access those updated methods on the Note model using the await keyword in our routes. We'll also briefly discuss the importance of catching errors that come from promises and async functions.

Resources

Jamund Ferguson: [0:00] Open your Note model and type import MapStore from "./lib/mapstore.js". Underneath your NOTES declaration, type const store = new MapStore() and pass in the string "notes.json". Now, go into createNote and right before the return statement, type await store.save, and then pass in the NOTES map. Let's do the same thing in our update and delete methods.

[0:24] One other change we need to make in delete is to store the results of NOTES.delete in a success variable, then call await store.save(NOTES), and then return success. For all the methods that use await, we have to make them async functions. Now, we've added async function to createNote, async to updateNote and async to deleteNote.

[0:43] With these changes, we have a way to persist data changes to our filesystem. The only thing we have to do now is to read them. Let's go back to the top of the file and right underneath our comment here, type store.read().then, and then pass in a callback function, which accepts notes. Inside of that function, we're going to say for (let [id, note] of notes) { NOTES.set (id, note); }.

[1:09] We're going to read the notes from the filesystem. For each one of those, we grabbed the id in the note itself, and then we set that note in our map and memory. We basically populate our memory store with the results of the store.recall.

[1:24] Now, let's go into our routes and use these updated methods. Open up routes/notes.js. In any place that we're not using an async function, such as create, update or delete, we now use await, const note = await Note.create. We'll make this an async function as well, const note = await Note.update now, and down here in delete we have await deleteNote.

[1:45] Let's go back and make sure we make update and delete async functions. With that we have everything that we need to do to read and persist notes to the filesystem. Let's go back and start our server and you'll see that it has a pretty long warning.

[1:58] There are two things we need to notice. First of all, you'll see UnhandledPromiseRejectionWarning. That means that somewhere in our code, we have a promise, which we forgot to catch(). That will lead the server crashes in the future. The next thing that it says is that there's no such file or directory notes.json. We don't even have the directory created yet.

[2:16] Let's go ahead and create a data directory. Go back into our note file and correct the missing catch(). You'll see here, we read the store with a promise, with then. Anytime we use a promise, we need to make sure that we are also adding catch() or the second parameter of then, which is an error handler.

[2:35] We'll use catch here, catch(err). All we're going to do when we find an error here, when we're trying to populate the notes is console.error(err).

[2:44] Now, we can start our server and we'll still see the same error. Couldn't read the file or directory notes.json, because it doesn't exist, but the server started without any other trouble. Now, we can go and post some new notes to our system. You'll see we currently have nothing in it.

[3:00] We can do -X POST -d title="hello" -d body="world". We'll just post three notes like that. You can see those are now saved in memory. Let's stop the server, restart it, make the exact same call, and they're all there. If you want to see how they're there, let's open up the file notes.json, and you can see they're all stored right here.