تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

مرور اجرای به‌روزرسانی‌های دیتابیس0:00

All right, our PWA break is over. And before we continue with that offline stuff, I'd like to wrap up the overall functionality of this app. We have a sidebar right now displaying notes and an editor where we can create and save them. But we need to be able to load up previous ones and make any changes to them, saving those changes in our local database. I'm going to go ahead and open up our source code. And back in the main Vue component, if we go to the top here, I've already made these individual notes links.

Opening Notes in Editor0:27

And back in the main Vue component, if we go to the top here, I've already made these individual notes links. Right now they don't go anywhere. But when we click them, I want to replace what's in the editor with the content of the note. So under this, I'm going to add a click event. And we'll use .prevent to prevent the default click event from happening. And we'll call this openNote. And we'll pass in the note that is in the foreach loop. And because of that, actually, I like having that below the foreach loop.

And we'll pass in the note that is in the foreach loop. And because of that, actually, I like having that below the foreach loop. That's better. Okay, so now we just need to create this method in our Methods object below. After our getNotes, we'll do openNote, notes. And now if we wanted to just replace the content of the editor with the content of the note, I could use something like this editor, which is the TipTap editor that's active right now. commands.setContent. And then pass in the note's content.

Set Content. And then pass in the note's content. Note Content. So now if we save this and go back to our browser, clicking on one of these notes in the sidebar will populate the editor with the content of that note. That's pretty great, but it's missing one key element. And that's the fact that if we go to save this note, we really don't have a reference point or anything that lets us know what the identifier of this note is to overwrite what's currently in the database. For that, we need the key, which is the created attribute.

Tracking the Active Note2:02

currently in the database. For that, we need the key, which is the created attribute. So instead, going back to our source code, I'm going to create a new data property. And it will be an object called ActiveNote, which is empty right now. And then what's going to happen is, whenever one of those notes is clicked, instead of just setting the editor's content as the note's content, we're also going to set the activeNote as that note. And this way we can reference it. So for instance, when we go to save the note, instead of creating a new one for a content that already exists, we can determine if there's an activeNote available and instead overwrite.

So for instance, when we go to save the note, instead of creating a new one for a content that already exists, we can determine if there's an active note available and instead overwrite what's currently in the database for that note. After changing this, let's go to the method where we are saving a note in the database. And now let's think this through. So right now we are saving a note in the database as a new note, generating that note object here, adding it to our main notes array, and then putting it into the database object store notes. We need to add functionality to this though to check if a note already exists. And if it does, overwrite it.

We need to add functionality to this though to check if a note already exists. And if it does, overwrite it. We could just add a conditional to this to check if there's an active note available, but I'm thinking about this in a slightly different way. You see, if we go back to our application, once we load up a note, the only way to get a new note added in here is refreshing it, giving us our blank editor. What we need to have is something over here in the sidebar, a button maybe, that when we click it, it clears out anything that's in the editor and prompts us for a new note. So let's go ahead and add something like that in right now. Up here at the top in our sidebar, I'm just going to add in a little header.

Adding All Notes Actions3:45

So let's go ahead and add something like that in right now. Up here at the top in our sidebar, I'm just going to add in a little header. Okay, so in our sidebar I have this AllNotes title here, which is a link that I can click on, and next to it I have this button with a plus that is also clickable. But both of these don't really do anything right now, so let's go ahead and change that. I'm going to add events to both of these. So for the AllNotes header, click prevent, and we'll call it showAllNotes. And then for the button, click event, addNewNote. So let's go into our methods and add both of these. showAllNotes and addNewNote.

So let's go into our methods and add both of these. showAllNotes and addNewNote. showAllNotes. And addNewNote. So for the showAllNotes, we want to do two things. We want to clear the editor and set the active note as an empty object. This will give us complete free space to then show a front-end list of all of the notes and their content. And then when we addNewNote, what I want to do is add a blank note to the database, add that same note to the sidebar, and set the active note as the new note.

And then when we add a new note, what I want to do is add a blank note to the database, add that same note to the sidebar, and set the active note as the new note. What this will allow us to do, it might seem a little convoluted, but this allows us to have one method for saving notes. Instead of saving either a new note or updating a currently existing note, each note, whether new or old, exists in the database and will have to be overwritten. So that way we can use the same method. Alright, for ShowAllNotes, this is pretty straightforward, so we'll start with that. To get rid of everything that's in the TipTap editor, we call this editor to get the editor object.

To get rid of everything that's in the TipTap editor, we call this editor to get the editor object. And then it's just Commands, ClearContent. That will remove everything that's in the editor. And then we just set this activeNote to an empty object. And we can try this out. So hitting AllNotes clears out the editor, and we have no more activeNote objects. Alright, on to the AddANewNote. So we need to add a new blank note to the database. Well that's basically what we're doing up here with the saveNote method.

So we need to add a new blank Note to the database. Well that's basically what we're doing up here with the saveNote method. So let's just copy this over. But instead of this editor.getHTML, our content is an empty string. Everything else remains the same though. We're also adding that same note to the sidebar with this method up here. And all we need to do is set the activeNote as the new note. So underneath the notes object that we shift to, we will set this activeNote as note. Now let's give this a shot. Adding a new note, and we see it appear here in the sidebar.

Updating Notes in IndexedDB7:25

Now let's give this a shot. Adding a new note, and we see it appear here in the sidebar. And if we click on it, it doesn't show us anything because it's currently empty. Now the last part of this is we need to change this saveNote method to update any note that's in here with the new content we provided to it. So let's go back to our saveNote method. And we're going to get rid of everything that's currently in the promise, since this is what makes up that AddNewNote method. Instead what we need to do, like most databases, is find the note by its id, change the content within it, and perform some kind of update or save action on it.

Instead what we need to do, like most databases, is find the note by its ID, change the content within it, and perform some kind of update or save action on it. Like with our getNotes method that we see here down below, we can chain on a few methods and get what we want. So this is going to end up with a request object, but I'm going to call this NoteRequest. And we call this database Transaction Notes. But unlike the getNotes method, we're going to be writing to this database as well as reading from it. So we need to provide the mode as ReadWrite. Then we're using the ObjectStore Notes.

So we need to provide the mode as ReadWrite. Then we're using the Object Store Notes. And instead of Get All, we are getting a single note. And that note is the active note, and its created date. Which remember, that's what we're using as the key in this database. So now we have a request that's happening asynchronously, and we need to handle a couple of different events that could happen whenever this finishes up. The first one is NoteRequest.onError. And it's a function that returns to us. And this is what happens if there's an error retrieving that note from the database.

And it's a function that returns to us. And this is what happens if there's an error retrieving that note from the database. And if so, we just want to reject with the message, Error saving the note in the database. And then the second event is an onSuccess, which is what happens when it successfully gets that note for us. Now the note that we find is going to be under eTargetResult. Just like when we find the database that we initialize. And we need to replace the content that's within this. We can just assign it to that note object. So the note's content is now this editor, GetHTML.

We can just assign it to that note object. So the note's content is now this editor, GetHTML. So it gets the HTML from our TipTap editor and adds it to the content attribute of our note object we just got from the database. So now we need to put this note back into the database and update the object that's already there. And in order to do that, we make another request inside of this onSuccess event. And this is an update request. And using the exact same object store that we did before, so we'll copy this here. And instead of Get, we're doing Put.

And using the exact same object store that we did before, so we'll copy this here. And instead of get, we're doing put. And it puts the note. Now this note already contains its ID as the created property. So by just putting the note object in there, it will understand the created date is its key and only update the value that we're expecting it to update, which is the one that we just grabbed up here earlier. And like with the original get of the note, we have two events that we need to process. updateRequest onError. And updateRequest onSuccess.

UpdateRequest onError. And UpdateRequest onSuccess. Now one thing that I do want to point out though is that we are copying two of the same events and lines that are in this right now. We're just calling get on this and then put on this. So I'm going to condense these down into a single variable instead. And we'll just call this noteStore. So noteStore.put and then noteStore.get. And we'll initialize noteStore as the database.transaction.notes with the object store of notes.

And we'll initialize noteStore as the database transaction notes with the object store of notes. All right, so this looks like it's all set. Let's go ahead and see this in action. So we'll pick a note. This one should be at the top, huh? So we'll do... Move this one up to the top. And we'll save the note. Now nothing happened.

And we'll save the note. Now nothing happened. And if we go to another note and then go back to this one, it is at the bottom. Why is that? Let's see if we refresh. Well now it's at the top. Oh, that's because when we save the note, we're saving it in the database, but we're not updating our main notes view array that actually renders out these notes. Only when we refresh did it pull in the new ones from the database and saw the actual updated value.

Syncing Notes Array After Save13:16

Now we could either do it up here before any of these events are handled. But in all honesty, because this database is being written to fairly fast, and I'm not anticipating my user to navigate away from and back to the same note in the time it takes that database to write, I'm going to ensure that it actually wrote to the database and make the change to our viewNotes array in the onSuccess event for the put request. But first we need to find the note that's being edited, specifically the noteIndex that's being edited, and that way we can then edit it in the notes array. So we'll create a variable, noteIndex is thisNotes.findIndex. And we go through each note and we return the note that is created. This might lead to a conflict considering we have a note object here and a note down.

And we go through each note and we return the note that is created. This might lead to a conflict considering we have a note object here and a note down here. So instead, let's call this just n, nCreated is equal to noteCreated. And once we find that index, we can do this->notes, noteIndex is equal to note. Okay, now let's see this in action. So we'll add a new item here. Well that actually won't show us anything because it would still be at the bottom. Let's add something in between these. And we'll save our note.

Rendering Notes List View14:42

Let's add something in between these. And we'll save our note. And then if we navigate away from it and back to it, it's in the position that it should be. And then refreshing, it's still in the position which is exactly what we expected. Alright, the last thing that I wanted to do is instead of having a blank screen here when I hit All Notes and just have everything cleared out, I want to display all of the notes that we have here along with their content in a sort of list. So back on our front end, what I can do is go up to the markup that shows the editor here.

So back on our front end, what I can do is go up to the markup that shows the editor here. And at this div above it, I can call v-if objectKeys activeNoteLength. So if the activeNote object has attributes in it, which means that an activeNote is present, then it will show this editor. Otherwise though, I want to show a list of the notes. I'll use this same div class and call v-else. Let's update this comment here too. And let's add the notes in here. Alright, a few things to note here.

And let's add the notes in here. Alright, a few things to note here. The first is notice that we're using this prose class again, so that anything underneath of this element or wrapped in this element is going to be styled by some nice tailwind CSS. I also have this createdOn and pass in the note created date to the date class in JavaScript and then output it as a locale string like we have in the sidebar. And then for the content, I'm just dumping it out into this div using v-html, which because we're saving it as html, it should just output exactly what our editor looked like just in this element.

Retrieving an IndexedDB item by idUpdating an IndexedDB itemClearing out the editor and improving the UI

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟