Now, in this course section,
we again learned a lot of important new things
and as we learned new things,
this app.js file,
which contains our Node Express code got bigger and bigger.
It's still not large
but it grew quite a bit.
And this overall is a simple page.
It's probably easy to imagine
that if you're building more complex websites,
this gets even more complex and bigger,
and hence, as a developer,
you typically wanna split your code
into multiple smaller pieces,
which are then each a bit easier to handle and maintain.
And that's what we did with our templates already.
Restaurant-item is a small, manageable piece
of HTML, for example,
which is then combined with other parts of this page.
And what we also did before with CSS
where we split our code across multiple files.
And we typically wanna do the same for our backend code.
And a good example here for splitting our code a little bit
and for also extracting some reused functionality
into a utility function,
would be this code where I access my stored restaurants
because we have the same code here
in the recommend route
and then also here in the restaurants detail route
for a specific ID
and then also here in that get route
where we get all the restaurants.
So we have the same kind of code
in different routes.
And such duplication is typically something you wanna avoid
because if I ever have to change something about that,
if I have to change the way we built this path,
I have to do it in three places.
Hence, what you typically would do in such a scenario
is you would create a brand new function,
which contains this code,
which then could be called from all these different routes.
Now, that is what we will do
but I also mentioned that we wanna split our code
across files to keep our files maintainable.
And therefore, I'll do both things in one go here.
I'll add a new subfolder here,
which I'll name util for utility.
This is absolutely not a name you have to use.
Instead, that's just a name I will use here
to put all my utility backend code into this folder
so that I have a folder with the public files,
which are shared statically,
that I have a folder for my templates,
that I have a folder for my data,
and now I also have a folder with some utility functions
that I use in my backend code.
And in there, I'll add my restaurant-file.js file
because this JavaScript file should hold the code
for working with that restaurant data file.
And maybe we therefore name is restaurant-data
now that I think about it.
And in this restaurant-data.js file,
I'll add a function, which I'll name getStoredRestaurants
because that is what this piece of code,
which I wanna reuse does.
It gets me this list of stored restaurants
by reading that restaurants.json file.
So now I'll copy that here,
that code snippet, which we are repeating so often
and I'll add that here in getStoredRestaurants.
Here I now just wanna return those storedRestaurants then
so that I don't just have them available in this function
but also in any function that calls this function here
because that's the idea behind getStoredRestaurants.
I am creating the standalone function
with this shared functionality
so that different places in my Express app
can call this function,
and can get the storedRestaurants,
which I'm retrieving here.
But for that to happen,
I need to make then accessible outside
of this function as well,
and that is what we do by returning them.
Now, in app.js, for example, here in the recommend route,
if I need my storedRestaurants, and I do need them
because I work with them here,
I have to use this function,
this getStoredRestaurants function here,
and then store the value that is returned
by that function, which is that array of restaurants
in the storedRestaurants here.
So here in the recommend route,
I can now add storedRestaurants,
and then call getStoredRestaurants like this,
and that should then return me this storedRestaurants array.
Now, it can be confusing
that I have storedRestaurants here in this function
and also here as a name
but that's only a coincidence here
or well, we have that name for historic reasons
because this code here in getStoredRestaurants
was in this place a couple of seconds ago
but we can now also rename this,
for example, to just restaurants
like that in all the places
where I was using storedRestaurants here.
Now I did rename it to just restaurants
and that's now the data which I'm getting
with help of my utility function.
But this code like that would not work.
And why would it not work?
For a couple of reasons actually.
For one, just using the function name like this
if the function is stored in a different file would fail.
We'll fix this later.
It would also not work though
because I'm then trying to write back into this file,
which is stored in this filePath
but filePath previously was a constant
in this route function.
It isn't anymore.
filePath is now actually a constant in getStoredRestaurants.
And you learned earlier in the course already
when we had a look at the basics of JavaScript
in the browser, and it's the same here
because as you learned,
NodeJS JavaScript generally works
just like browser-side JavaScript.
There you learned that if you have a variable
that is defined in a function,
it's not by default available
in other parts of your code.
So in this app.js function here,
I can't just use filePath.
It is defined in this getStoredRestaurants function
but it's basically also captured in there.
You don't have access to it in other places.
Now, a good way of solving this
would be to simply add another utility function
in this restaurant-data.js file in the util folder,
and this utility function stores our restaurants back
into this file.
So here we could name this storeRestaurants like this,
and I would expect that I get the restaurants
that should be stored as a parameter.
So here I get my restaurants
or the storableRestaurants, however you wanna name this.
And then in there inside of this helper function,
we then reach out to the file to store our data.
So we copy this line of code,
writeFileSync, and add that here in storeRestaurants.
With that, we still don't have access to the filePath
because that's still in a different function
but what we could do now
is we could just move that out of getStoredRestaurants
and turn this into a constant,
which is available in this file as a whole,
and if you do that,
this will actually be accessible by all the functions
in this file.
Not in other files, I can say that,
but all the functions of this file.
And therefore, filePath now is available here
in getStoredRestaurants, but also here in storeRestaurants.
And in storeRestaurants, I now just wanna make sure
that I store my storableRestaurants like this.
Now we outsource both the readFile
and writeFile functionality into separate functions
that have some extra functionality inside of them
in this utility file.
Now in app.js where I wanna write to this file,
I can just call storeRestaurants
and pass my updated restaurants,
which is this restaurants array
to which I pushed a new restaurant to storeRestaurants
because storeRestaurants, this function which we just added,
does have this storableRestaurants parameter,
which is that value that it wants
to then store it in our file.
So we should make sure that we pass a value
for this parameter here.
And I know that these were a lot of steps,
and we did move quite a bit of code around
but refactoring code like this
is a common task to avoid code duplication
and to keep your individual code snippets short,
concise and maintainable.
That's why I'm doing this.
Still, unfortunately, we're still not there.
This code would fail,
and I'll tell you why and we'll fix it in the next lecture.