So, as I mentioned,
by the end of the last lecture.
In this one, we will now make the bookmarks data persist
across page loads.
And for that, we're gonna use local storage.
And once again, this will now become quite easy,
and quite straightforward,
because we already have our entire project structure
so nicely set up.
So storing data in local storage
is of course all about data.
And so that will have to be implemented here in the model.
So let's actually take a look here at our flow chart again.
And so now this is all about loading bookmarks
from local storage and storing bookmarks to local storage.
So when should the bookmarks be stored to local storage?
Well, that happens whenever the user
bookmarks a recipe.
And of course that also when the user
unbookmarks the recipe.
So in either of these cases,
the current bookmarks array
basically needs to be stored to local storage.
Okay, so what I just said,
is that whenever we add a bookmark or delete a bookmark,
we need to persist that data.
And so let's add a function here,
which we can then call in these two functions.
So this one we don't need to export
because we simply will call it in these other two functions.
So persist, bookmarks.
And then here, remember,
all we have to do is local storage.setItem.
Then here we can give that item a name.
So that's bookmarks.
And then here, we need to set a string.
And we do that by calling Json.stringify
and then with the object
that we basically want to convert to a string.
And so that is state.bookmarks,
and that's actually it.
Now, all we have to do is to call this function
in these two places.
And that's already the first step
and we can actually try that out already.
So at least seeing it in the console.
So let's bookmark this one and also this Greek pasta salad.
Right, so both of them are now here
and let's come here to application and then local storage.
And so here it is already.
So here are the bookmarks with these two recipes
that we just stored.
And now, as I reload the page,
you see that the data is still here.
Now, of course it is not yet back here.
So just because the data is still in local storage,
doesn't mean that it's magically gonna show up here
because we didn't write any code for that yet,
but let's now actually go do that.
So basically when the page is loaded,
we then want to run a method
which will basically render the bookmarks here.
All right.
So the first step in doing that,
is to actually get the bookmarks out of the local storage
and back into our code.
And then after that, we can then as I just said,
render them back here to this bookmarks view, okay?
So we have to code for persisting.
So for storing the bookmarks in local storage here,
so let's now also have to code for taking them out
also right here.
And let me simply write an initialization function here.
So an init function,
and then right at the beginning,
I will call that init function.
And here, of course, missing the function keyword.
And so here we need to do the opposite.
So LocalStorage.getItem,
and then remember it is called bookmarks.
And then we also need to store that somewhere
and I'm not storing it directly into our state,
because this data might not be defined actually.
So we might have nothing of course, in the storage.
And so only if there is storage,
then we want state.bookmarks to be
Json.parse,
which is basically to convert the string back to an object.
And so here we are now calling this function
right in the beginning and then
just to see let's then immediately log state.bookmarks
to the console.
Okay, so here we have a lot of logs.
So let's go here to line 11 of these two
and line 114 of the model.
So model, now this one actually,
is the one that I just did,
but here we apparently have some console dot logs
that we don't need.
So here and here,
and in fact, let's close these here
and actually all of them for now.
And so here, right?
Immediately we have the local storage.
Now, for some reason, this recipe was not find let's reload.
Well, that's weird.
And apparently we broke something in our code,
but let's worry about that in a second.
So for now, what matters here,
is that we actually got the data back from local storage.
So let's see if this has anything to do with the code
that we just wrote here.
Well, that's very weird.
So now it is back to working for some reason.
So let's actually log the error
that is actually happening to the console.
So here let's set that back to cause that error,
but then here in the controller,
so the one that is responsible for loading the recipe.
So here, right now,
we are only rendering the error to the user interface,
and we are doing that with this nicely formatted error
that we defined in the recipe view.
But so let's not actually also log the error itself
in the console so that we can see
what is actually happening.
So console error with error.
And so now we get text content of undefined
coming from controller at line 34.
Okay, that's just the log.
And so here we have a stack trace.
And so the error itself is originating in line 25.
So it is here when we update the bookmarks view.
Okay, so this is where the error basically comes from.
And so this is how we use this so-called stack trace.
So here we can then follow exactly what happens.
So here we then need to go to view 27,
which is where this update is defined 10 for each
and then line 37.
So line 37 in the view,
and so that is right here.
So some kind of problem
with updating the bookmarks view.
So apparently we're trying to set the text content
on some element here that doesn't yet exist.
So maybe we are simply calling this method here
a little bit too soon.
So that's moved out here to the end.
So updating a bookmark's view.
So we still have an error.
So this might be a good time to use the debugger.
And I hope that with this, we will be able to find the bug.
And if you're not interested in watching me find this bug
and please feel free to jump to some later point
in the code.
So you see that at this point,
the recipe has actually loaded.
Okay, and so now here we are at the debugger.
And so let's now go to the next step,
which is this one here.
Then we go into bookmarks view.update.
And at this point, the data here,
is actually already the data that is coming
from our local storage, right?
So this bookmarks here is at this point already loaded.
So right here we do that right at the beginning.
And so therefore the bookmarks,
so model.state.bookmarks here is already defined.
So that's these two objects right there.
Let's actually see the scope here.
And so indeed that's these two recipe objects, right?
So here we also have the entire call stack.
Okay, now let's keep going.
So the new markup,
then here we go through all of this.
Okay, once again,
all right, so here we are back.
Whoa, what's that?
Ah, so I just hovered over the string,
which has all of this.
So that's this markup that we just generated
then here let's generate this dam, okay?
And here are the new elements and the current elements.
So right now here, inside the current elements,
let's see what that is.
So that's all of the elements
that are basically right now
in that empty bookmarks panel, right?
Now, and do you see that the length of this one here is five
and this one here is 14.
And so I think I'm starting to see the problem here.
So these two arrays are the arrays
that we are basically comparing here, right?
So we have this hole for each loop
to compare the elements in these two arrays, right?
Because the goal of this method is to not add new elements,
but only to replace some text and elements
that already exist.
However, right now this bookmarks here is still empty.
And what does update here is trying to do,
is to now insert the data in there.
And so that should not happen, okay?
And so I'll actually quit this now,
by going back here,
getting rid of this and simply reloading.
So let's get this down.
And so in order to prevent this,
the first thing that we need to do now on the page
is basically render the bookmarks
and remember that's what happened
right at the beginning when we load the page.
So let's go to the bookmarks view
and here create a new handler.
So add handler render,
which receives an handler,
and then window.addeventlistener and load.
And then we will immediately call this handler.
Okay, and so here,
we already imported it.
And so here at the very end,
let's create then the handler function.
So the controller control and bookmarks,
and then all that we will do
is actually take bookmarksview.render
with state.bookmarks.
And again, that is actually model.state.
And now let's ask the first of all thing here,
do bookmarks view.addhandlerrender
with the control bookmarks?
And so now we are back to working
and the two bookmarks from before are now actually here.
All right, so with that we solved the problem,
because now as the page here tries to then
updating the bookmarks view,
the bookmarks are already there.
And so then there's nothing to update really.
So we can actually move that back up here, I believe
actually this one as well.
So let's try that again.
And yeah, so this is a bit of a more,
a natural order
now, okay.
And so now of course I can click here
and then this gets selected
and everything keeps working the same.
So we don't even need to search functionality
to be able to switch between our recipes.
And of course, if we unbookmark,
then that is gone, and as we reload the page,
then we only have this one,
then let's remove all of them.
And then as this was re-rendered, right?
Then we got this error message here back.
And of course, if we reload now,
then we have no bookmarks at all, again.
Now just to finish,
let's quickly add like a quick function here for debugging.
Let's call it clear bookmarks,
which is simply a function that at some point
we might want to call,
but again, only during development,
so clear 10 bookmarks.
So when I'm working with this,
then sometimes I need to do this.
So clearing all the bookmarks.
So let me add a couple of ones here.
So this one and this one.
Okay, and now as they reload the page,
it should then clear all of them.
Well, it didn't for some reason.
Oh, and that's probably
because this one here happened first,
so let's take this one out, do that again.
And now the bookmarks are gone.
Okay, but by default,
this will, of course be turned off
because otherwise our application is not going to work.
So here is the hot pizza dip.
And it is still bookmarked after we reload the application.
And so let's quickly to finish,
check out our flow chart,
but I'm pretty confident that everything is implemented.
So when the user clicks a bookmark,
it will then mark the selected bookmark here.
And of course it will render the recipe.
When the page loads,
then the bookmarks are loaded from local storage
and they are rendered.
So check here as well.
And when the user bookmarks a recipe,
then it gets stored to local storage.
So check here as well.
And so we just implemented all of this
or rather complex part.
So now it's finally time to take a break
and take an overview of what we need to implement next
in order to finish this application.