Making the title unique
The first step to make the title unique will be to loop through all of the notes after we load them in and check whether there are any duplicates. If there are duplicates, we'll not call the following two lines:
notes.push(note);
fs.writeFileSync('notes-data.json', JSON.stringify(notes));
If there are no duplicates then it's fine, we will call both of the lines shown in the preceding code block, updating the notes-data file.
Now, we'll be refactoring this function down the line. Things are getting a little wonky and a little out of control, but for the moment, we can add this functionality right into the function. Let's go ahead and make a variable called duplicateNotes.
The duplicateNotes variable will eventually store an array with all of the notes that already exist inside the notes array that have the title of the note you're trying to create. Now, this means that if the duplicateNotes array has any items, that's bad. This means that the note already exists and we should not add the note. The duplicateNotes variable will get set equal to a call to notes, which is our array of notes.filter:
var duplicateNotes = notes.filter();
The filter method is an array method that takes a callback. We'll use an arrow function, and that callback will get called with the argument. In this case, it will be the singular version; if I have an array of notes, it will be called with an individual note:
var duplicateNotes = notes.filter((note) => {
});
This function gets called once for every item in the array, and you have the opportunity to return either true or false. If you return true, it will keep that item in the array, which will eventually get saved into duplicateNotes. If you return false, the new array it generates will not have that item inside duplicateNotes variable. All we want to do is to return true if the titles match, which means that we can return note.title === title, as shown here:
var duplicateNotes = notes.filter((note) => {
return note.title === title;
});
If the titles are equal, then the preceding return statement will result as true and the item will be kept in the array, which means that there are duplicate notes. If the titles are not equal, which is most likely the case, the statement will result as false, which means that there are no duplicate notes. Now, we can simplify this a little more using arrow functions.
I'll use the arrow function, as shown here:
var duplicateNotes = notes.filter((note) => note.title === title);
Here, I have deleted everything except note.title === title and added this in front of the arrow function syntax.
This is perfectly valid using ES6 arrow functions. You have your arguments on the left, the arrow, and on the right, you have one expression. The expression doesn't take a semicolon and it's automatically returned as the function result. This means that the code we have here is identical to the code we had earlier, only it's much simpler and it only takes up one line.
Now that we have this in place, we can go ahead and check the length of the duplicateNotes variable. If the length of duplicateNotes is greater than 0, this means that we don't want to save the note because a note already exists with that title. If it is 0, we'll save the note.
if(duplicateNotes.length === 0) {
}
Here, inside the if condition, we're comparing the notes length with the number zero. If they are equal, then we do want to push the note onto the notes array and save the file. I'll cut the following two lines:
notes.push(note);
fs.writeFileSync('notes-data.json', JSON.stringify(notes));
Let's paste them right inside of the if statement, as shown here:
if(duplicateNotes.length === 0) {
notes.push(note);
fs.writeFileSync('notes-data.json', JSON.stringify(notes));
}
If they're not equal, that's okay too; in that case we'll do nothing.
With this in place, we can now save our file and test this functionality out. We have our notes-data.json file, and this file already has a note with a title of secret2. Let's rerun the previous command to try to add a new note with that same title:
node app.js add --title=secret2 --body="Some body here"
You're in Terminal, so we'll head back into our JSON file. You can see right here that we still just have one note:
Now all the titles inside of our application will be unique, so we can use these titles to fetch and delete notes.
Let's go ahead and test that other notes can still be added. I'll change the title flag from secret2 to secret, and run that command:
node app.js add --title=secret --body="Some body here"
Inside our notes-data file, you can see both notes show up:
As I mentioned earlier, next we will be doing some refactoring, since the code that loads the file, and the code that saves the file, will both be used in most of the functions we have defined and/or will define (that is, the getAll, getNote and removeNote functions).