Transcript from the "CRUD Methods: Read & Delete" Lesson
>> The next thing is, let's find notes. So this one's kinda cool, a little bit of filtering. So we can say export const findNotes, and this one takes in a filter, so a string. And basically what we wanna do, is we wanna use that string to just do a very cheap, super broke full text searching on some strings.
[00:00:28] We're just gonna use the dot includes on a string. That's the poor person's searching. So we're gonna do that to find a note that matches whatever search criteria that you put in. So, let's do that. In order to do that, we have to get all the notes. So let's get all the notes.
[00:00:43] We can say await notes = await, and then getDB(), and we're gonna destructure those notes like that. So let's get those notes. And then once we have those notes, we can just say, let's just return the notes.filter, which returns a brand new array. So we'll say, if the note.content, remember notes have content, we put that here.
[00:01:15] Notes.content, I need to normalize the strings because when you match characters, capitalization matters. So if someone saved a note with all caps or one capital letter, but they wanna go search for the same word without a capital letter, it would not match. So I'm going to normalize it by just either upper casing everything or lower casing everything.
[00:01:34] So I'm just gonna lowercase everything. So toLowerCase() this content, and then .includes this filter.toLowerCase(). So basically, yeah, I'm just doing a filter over the notes array, and checking to see if each note's content includes whatever the filter was passed in. So what does this actually look like? So a note might have a content like this, walk my dog today, this might be a note, right?
[00:02:11] And then a filter might be something like this, my dog, right? So this would match, right? And also if it was like this, this should still match because I lowercased everything. Because this string includes this string. What if it was like, that would not work because includes is not that smart.
[00:02:40] Okay, and filter just returns a brand new array. So findNotes should return an array of filtered note that match, or an empty array of notes that don't match, so should be good that. Okay, we got findNotes. Now we need to do removeNote. So this takes in a note id.
[00:03:00] This is why I was given all the nores ids, cuz you wanna be able to find a note by an id and do something. In this case, we wanna remove it. So in order to remove a note, we need to first get all the notes. Second, we actually don't need to do this part, the only reason I'm doing this part is to basically return undefined if it doesn't exist.
[00:03:24] But we don't have to do this part right here, because we're already kinda doing it here, but basically we'll do this part to see. First, we'll check to see if, is there even a note in our database that matches this id? And then if there is a match, then we'll go ahead and create an entirely new notes array since that match, so basically remove it.
[00:03:44] And that's what this filter is doing. So a filter, again, it makes it an entirely new array, but it won't include it, I'm sorry, it'll only include notes whose ids don't match this id, which we know there's at least one in there because this was true. And then we'll save that entirely new notes to the database, and then we'll just return the id.
[00:04:04] And then if this is false, it'll go to after this if statement, which is nothing, so it'll just return undefined. So let's do that. So, const remove or export const removeNote, take an id, async. And yeah, I don't have to put parentheses around this if it's just one argument on the arrow function, by the way.
[00:04:33] So this doesn't need parentheses if you don't want to. If it's more than one argument, you gotta put parenthesis. So let's get the notes. Wait, let's destructure this, getDB, so let's get those notes. And then we just need to see if there's a match. Const match = notes.find ( note whose note.id= id).
[00:05:03] If there is a match, Then we need to say, const newNotes= notes.filter( on a note whose note.id does not equals the id). So make a new array with every note that doesn't have that matching id. So, theoretically, we're not removing the one that matches, we're just making a new one and not including it.
[00:05:34] So that's the difference. We could remove it. We could just say, cool, give me the index of that note and then remove it from the array. But I'd rather do a non or a mutable approach, as in, I'm not modifying this notes array, I'm just making an entirely new array.
[00:05:57] Okay, so we got new notes. So now we'll save this, so await saveDB. It's an entireDB, so we gotta put the whole object back in here, right, this whole object. So, and that has a notes property, which is newNotes. And then we can just return the id. Any questions on that?
[00:06:31] It's a really convoluted process. Like I said, we didn't really need to do this match. We could have just said, hey, just go ahead and do this filter and do that. But I wanted to make sure to do undefined, yes?
>> Line 26, double equals?
>> Yeah, sorry, there we go.
>> Or triple.
>> There we go, yep. I know people are looking at it and they're like, what was he doing? [LAUGH] Yeah. Cool, any questions?
>> So for this example of that function, you would need to have that entire date string or date number for that id, you'd need to know that?
>> Yeah, you would need to know the id. Yep, you will have to know it. But if you think about it, how does that work in reality? You yourself wouldn't need to know because the UI would know, right? Imagine this was a list of notes and I click the delete button on it.
[00:07:34] Okay, that thing that I clicked on knows its own id, so it sends it up. So the person that clicked it wouldn't know what the id was, but the thing that was clicked on knows what it was. We don't have a UI. So yeah, you would need to know the id of the one that you wanna delete.
[00:07:49] So yeah. I guess another way around it is you can give notes unique titles, and then you can delete it from a title. But yeah, yes?
>> Is there a reason you're returning a new array instead of mutating them?
>> Is there a reason? I've just practiced a habit of being immutable since, I don't know, I've been doing this since flux was a thing.
[00:08:16] Have you ever heard of that? [LAUGH] I mean, to be honest, most people just avoid mutating anything because it can cause side effects. I know in an early example I did do a mutation. I forgot where, I think in the DB.js, right here, I did a mutation here.
[00:08:30] So it's not that I'm stuck on immutability. It's just that I just try to avoid side effects as much as possible. So creating new instances, it's typically easier than mutating previous ones, especially if you have a lot of logic going on. So for me, I think I've developed this pattern of not getting myself into trouble with things later when stuff starts breaking, and mutating stuff is one of those things that always get me into trouble.
[00:08:59] So I just try to stay immutable. But there can be downsides to that as well if you're in a constrained environment, like for instance, when I worked at Netflix, we had like a memory budget on a TV. Cuz TVs only have so much resources, so just creating new objects out of nowhere, it's pretty taxing and expensive.
[00:09:19] So you have to work around that. So it really just depends, but I'm on my machine on a MacBook, so I'm gonna make as many objects as I want. Cool, good question. What else we got? We have our last one, remove all. Then this one is just, it's so free.
[00:09:37] It's just handed to us. So removeAllNotes, it's basically a one-liner here, and that's just await. And we don't even need await here, we can just return the set. What is it? What do I have? There we go, saveDB. We can just say, saveDB, notes, empty array, just reset it.
[00:10:03] So if you just have one line of code after the arrow, you don't need the brackets, you don't need these brackets, and the return is implicit. It's implied that this is returning. You don't need the brackets. And I don't need to async await this cuz I don't have a code running after it.
[00:10:21] So I can just return it, and it's a promise, and it works. So I don't have to async await this, cuz I'm not doing anything after it, so I don't need to wait for it to be done. Cool, although I did await here, I don't have to. It works either way.
[00:10:39] You don't have to. Okay, I'll talk about what everything does as I was doing it, but if you wanna see what everything is done, I have an explanation for every function here, you can take a look at all of that. But I guess I could just walk through it right quick.
[00:10:56] So newNote, takes a note, takes in tags, creates a new note, saves it in the database without overwriting the entire database. getAllNotes does exactly what it says, it gets all the notes in the database and returns that. findNotes takes a string and grabs all the notes, and checks to see if any note in our database has this string as a substring for its content, and if it does, it returns all those matching notes.
[00:11:26] removeNote takes an id, checks to see if there is any note in the database with that matching id and removes it. It actually doesn't remove it, it just creates a new one, sends that one. And then removeAllNotes just resets the database to nothing.