This episode is for members only

Sign up to access "Build a Notes App with Alpine.js" right now.

Get started
Already a member? Sign in to continue
05. Listing notes


The next logical step is to output the notes that we have.
So when we start typing here, we can see the title and the body update. Then we'll tackle the last updated time and then eventually order these in the order that they've been edited. We'll then go ahead and look at our local storage because, of course,
we don't have to keep refreshing the page to get a new note every single time. We want to be able to actually create new notes and have these saved out. But let's go ahead and look at listing through our notes. Now, this happens down here for this list item.
So let's go down and look at what our state kind of looks like in this data. What at the moment is just a list of array items that are being pushed to in the order that they've been created. That's not really what we want.
We want a getter that's going to order them by the last edited date. Now, we're not quite there yet because we're not storing any kind of date. So we're going to implement that method a little bit later. Let's just look at using data on its own first of all to iterate through them notes.
And the really cool thing about this episode is once we start editing, we're going to see that automatically update the state of the notes in the left hand side as well because current is just grabbing the current note from our single source of notes that we have.
So let's go up to our list item and let's start iterating through this and see what we can do. So to do this, we're going to wrap the entire thing in a template so we can iterate with Alpine.
So let's just go ahead and collapse this again and just end our template in here. We're going to go ahead and indent all of that. And we're going to use an x4 inside of here. Now, of course, this needs to be an Alpine component.
So it would probably make sense that the overall wrapper here uses x data to make this an Alpine component. Okay, so we're going to say for note in, and we're going to access our store, and we're going to say
We'll change that later, but for now, we'll just directly access our data. We need to make sure that we key this so Alpine can keep this up to date when things change. So we're just going to use the ID because that's a unique identifier for
each of our notes. And if we come over and give this a refresh, notice that there's not much difference because we only ever have one note inside of our store. If we started with a note that already existed, so for example,
had an ID of one, a title of existing note, and a body of a new body. If we come over and give that a refresh, and interestingly, we get an error here. The reason for this is if we think about when we create a new note,
that's if we don't have any existing notes, which is what we were speaking about earlier. Now, the error we get here is cannot read properties of undefined reading title. That's coming from our model, if we just go up to where our model is
with our input. At the moment, we don't have a current note because the only way to set a current note at the moment is when we create a new note. So really, what we need to do is fix this up first, so the note that already exists
within our notes, which should be being set, is not being set. So inside of here, what we can do is go ahead and set our current note that's technically not in storage, but kind of is faked, to the current note. So we're going to extract this out to a method.
So let's say setCurrentNoteByIndex, that kind of makes sense. And the index that we always want to set from here is just the top of the stack. So we're just going to say 0, of course. Arrays in JavaScript are 0 indexed.
So let's create out a method in here to do that, setCurrentNoteByIndex. And all this is going to do is just take in the index, and it's going to go ahead and set the current note ID that we have already set when we create a new note to the index of the data that we have.
So that's just going to be this data. And then we're going to pass in the index, and we're going to grab the ID from that. So let's just recap really quickly. If we have notes in storage, if we already have notes that exist, grab the first one
and set it to the current note. And by doing that, what we're doing is we're grabbing the index from our notes, which is just called data, and grabbing the ID. And then that getter here will actually bring back an object, and we shouldn't see this
error. So if we give that a refresh, there we go. We have set the existing note inside of our editor view, which is now hooked up to the model in the title and the body.
And we see exactly what we want. Now we only see one item in here. That is because we've not created a new note when we have hit the page, because we're just setting the current note that exists.
If we just go ahead and duplicate this line down to create another new note, and again, let's give this an ID of 2 and say another existing note, we should see 2 there, because we're now iterating through that. Now, of course, at the moment, we can't see the title or the body.
Let's fix that up, and then we can move on. So let's go up to our list item. We're now iterating through this as note, so we can access the note inside of here. For the note title just here, we're going to go ahead and bind this in with xtext.
So let's just say note title, and let's do the same thing with the body preview. We can get rid of the text in here and use xtext to say note body. So let's check this out. We've got our existing note in here, which is now the zero index, which we're setting
just here, and that means that this note is currently in view. Now when I start to edit this, you can see that on the left-hand side, this is going ahead and keeping up to date. And that is because the current note is a direct reference to the object that we have
set inside of this side with xmodel. So we can go ahead and update that and see this in real time. Now at the moment, there's a couple of issues with the way that these are output. If we just go over and just get rid of the title here, you can see that we literally
get represented with nothing. That's obvious because we've got rid of everything in this input, and we end up with an empty string. So what we really want to do within here on the note title is have a little condition
to say, well, if the note title is empty, we want to display something else if this doesn't exist. So we can just use an or operator and say untitled note. So what that will do is if the note title is not available, it will give us untitled
note. And we could do the same thing for the body as well. So let's go and maybe not do that. So I think we'll leave that as it is.
So if there's no body, we just see nothing there. Now the other thing about the body is that if we have a huge body, so if we just go ahead and duplicate this over and over again, we end up with pretty much a complete replication of everything that we've typed in here.
It would be much better to do a substring on this to cut this length down and make it a little bit easier to read. So we're going to go ahead and say note.body.substring. And what we're going to do is start at zero.
And we're going to go and use math min because we want to either show the body length if it's less than 100, or if it is 100, we want to cut it off. So min is going to select the smallest value out of the two options we give here. So 100, it will cut it down to 100 characters if it's over 100 characters.
Or if the body length of the note is under 100 characters, it will go ahead and select that instead. So just the smaller out of these two numbers. If the body length was 50, it would choose that one and it would cut it down to 50.
Or if it was over 100, it would cut it down to 100. So let's go ahead and just try that again by just duplicating this over and over again. And you can see we end up with this being cut out however much more we type in there. And again, if it's less than this, it won't cut this down to 100, it will cut it down
to the length of the actual body. Okay, so now that we've done that, we're pretty much set up with our title, which is being bound to here, and our body, which we can now edit. So that is listing out all of our notes.
We can't click on these at the moment to switch notes. We're just getting the current note that's at the very, very top of that stack, which at the moment is just the first one that was created. So we have a little bit more work to do to make this work nicely.
11 episodes 55 mins


Put Alpine.js state management to the test by building a fully working notes app in the browser.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.