We'll create a new Map()
data structure to store Notes that are passed into our API in memory. With that in place we'll create a model called Note.js
that has the responsibility for saving and manipulating those notes and saving them back into our data store. After we hook up the our routes to call into our Note model and confirm that it all works.
To power our API we use some modern JavaScript syntax:
Jamund Ferguson: [0:00] Type npm install uuid. We'll use this package later to create ids for our Notes.
[0:05] Now create a folder called model, and inside that a file called note.js. The Note model's job is to provide our application with a way to store and manipulate and remove notes from our system. As much as possible, it should obstruct away the underlying details such as how it's storing them. For now, we'll store our notes in memory in this Map.
[0:23] Type const NOTES = new Map(). A good place to start when modeling data is defining what data structure we'll be using. For now, I'll just add these in the comments.
[0:33] Let's build out our list function. Type export function getNotes(), and inside the function type return Array.from(NOTES.values()). Every map in JavaScript has a values method that returns an iterator as its values. To get an array from that we use Array.from.
[0:48] For create type export function createNote(). For the parameters we only need title and body, but because these parameters could grow at any time, I prefer to use destructured parameters. By wrapping those two arguments in curly braces, we can now change the order, add new parameters to the function.
[1:06] Inside our function type const id = uuid(). At the top of the file, we'll import the uuid module by typing import { v4 as uuid } from "uuid". Now we need to create the value for lastEdited. For that we'll use Date.now, which gives us the number of milliseconds since 1970.
[1:25] Now we have enough to construct our note. const note = { id, lastEdited, title, body }. That's our note. Let's go ahead and add it to our map. NOTES.set. Pass it the id as the key, and for the value, the entire note. Now, we'll end by returning the note.
[1:47] Let's move on to updateNote. Type export function updateNote(). Pass in the id and again, the title and body, since we're updating an existing note. First, we'll check if the note already exists. if (! NOTES.has(id)) then we'll return null. I'll scribe the existing notes since we now know it exists. const note = NOTES.get(id).
[2:07] Then we can set the title. Type note.title = title. Here we use no coalescing syntax, type ?? note.title. This syntax is saying if title doesn't exist, just apply the existing note title to note.title. We'll do the same thing for body. note.body = body ?? note.body.
[2:27] That's all we need to do to manipulate the note. The only thing to watch out for here is instead of returning the note directly, we're going to return a copy of the note. Type return { ...note }. We're using the spread operator here to spread the contents of the note into an object. That essentially gives us a fresh copy of our note.
[2:44] That way, if any of the routes that are calling updateNote or any of our other model functions decide to manipulate that, it won't manipulate it in the data store. Let's go up to createNote and make sure we're returning a copy here as well.
[3:00] GetNote is pretty straightforward. Type export function getNote(). Will take an id. First, we'll check if the note exists, if (! NOTES.has(id)) return null. Since we know that it exists, we can grab the note, const note = NOTES.get(id), and we'll return a copy. Finally, delete. export function deleteNote, taking an id. Here, we can simply call NOTES.delete(id).
[3:25] Delete on a map such as the notes variable here will return true or false based on whether or not the id exists. We'll restart our server.
[3:32] Let's go ahead and hit the route for /notes. You'll see that it's now returned as an object with the key of notes and the value of an empty array. Let's add a new note, type curl -X POST -d title="hello" -d body="world," and post that to the same URL. It looks like over here on the left, you can see that the new id was created. It saved the title and body as we set it.
[3:58] Now we can hit our notes. You'll see that we do return the note that was added. Let's go ahead and try our update route. curl -X POST-d title="updated" passing /notes/ and then the id. We can see here it's saved in our logs with title as updated, body as world. Let's go ahead, /notes/id, and you'll see it is returned as we'd expect it to be.
[4:22] Finally, let's try delete. Got our curl here -X DELETE. Seems to have worked according to our log. Let's check the list now. It's gone. Looks like all our routes are working pretty well.