Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
So far in our code we've been using and requiring all of these Node modules for example EJS or Express
and body-parser.
But how does it actually work?
If we take a look inside our Node modules and we go and just find where EJS is, and we click on
ejs.
js, if you scroll down it, you can see that there is-- maybe there are some variables which we already
know about, there's some functions but there's also a whole bunch of these exports: exports.this export.
that.
So what exactly is that?
Let's try and understand how our Node modules like EJS, Express, body-parser actually work by creating
a module of our own from scratch.
Currently we have this thing down here which basically just generates the current day in a particular
format that we desired.
Now if we were to refactor our code right now then this is probably one of the first things that we
want to package into its own module because it doesn't really belong here in the app.js. You can imagine
that as our app.js gets more and more complex, then we have more routes,
we have different get, post routes all over the place.
Code that's not strictly related to the route shouldn't actually be in here cluttering the app.
js.
How would you normally solve this?
Well we could go ahead and create a new file
let's just call it date.js and this could be our own little module for generating the current
date.
So let's go ahead and cut all of this code.
And we're going to paste it inside date.js. And of course we have to again say jshint we're
using esversion 6.
Now we have this date.js module which does all of the hard work to find the date and change it
to a particular format.
But how do we get this day back into our app.
js and use it inside our root route?
Well maybe we could wrap this thing inside a function, we could call it getDate. And this function
all it does is carries out all of this code and then it simply returns the result of all of this.
So at the end we get this thing called Day which is what we've been previously using inside our root
route.
So what if we just returned day
so we get an output out of our function?
Now we have this function and we have a way for it to return the thing that we want.
How do we actually export it?
How do we get it out of this date.js?
How can we make it available elsewhere if it's needed?
Well this is where Node comes in to the rescue.
So if you take a look at the docs for the latest version then if you read through all of this maybe
not all of it but the relevant parts, then you can see that there's a section on modules. And the module
object is basically something that gives you a reference to the object that represents the current module.
So that means that inside this module here date.
.js, we have access to this thing called module.
And I can go ahead and just log my module. And if I were to use this module then I can require this module
to run all the code inside here.
So for example, up here instead of requiring body-parser and Express I'm going to create a new const called
date and this simply requires my new date module.
Now because our module is local and has not installed using NPM then the way we access it is a little
bit different.
We have to use that thing that we saw previously with the directory name +
and then we have to locate our date.js.
So now what this will do is we're saying we're requiring a module and it's located at the current directory
name and then we add /.js in order to access this particular file.
So now if I hit save and I run my code using node app.js making sure that you're in the right
position then I will end up with my module printed out inside my console.
So whenever I say require this module then it'll go into this module and it'll try to run all of this code.
Now over here you can see what it's running is that log statement. And we've logged that module object
so this is the object that represents our date module. And you can see it's got a whole bunch of interesting
things in here.
For example an id
so this is where it's located which currently is in my local directory right? Something called WebDev
/todolist-v1/date.js which is where you can see it here.
And then you've got a whole bunch of other things such as
it's got a parent module right?
What was the model that actually launched it or required it?
Well in this case it's something called app.js. And that thing has a whole bunch of children including
this date module.
So we've also got other children such as Express and body-parser and EJS and it's also got other things
associated to it.
Now if we take a look at our module object that represents our date module you can see it's also got
this property called exports. And export seems to be some sort of Javascript object as denoted by those
curly braces.
But at the moment it's completely empty.
So there is nothing that our module is exporting.
If we take a look back at the documentation and we navigate to this part where it talks about module
.exports, then you can see that this is also a Javascript object and it's created by the module system.
So what it allows us to do is to basically say module.exports do something or is equal to something.
And then that means that in another file, we can simply tap into that module and use some of those exports.
So let me show it to you in our code.
Now instead of console logging our module, we can simply write module.exports.
Remember the s
this is a really common mistake.
And then we set it to equal say hello world
maybe. Now this current date module exports the string that's Hello world.
So if we go back into our app.
js whenever we require our module it gets bound to something called date.
And over here we can simply log our date object and that will be equal to whatever it is that we exported
out of this module.
So now if I had back into my console and I stopped my server and rerun it, you can see that my app.
js is now printing
Hello world.
There's no log statements over here.
And this is because I'm exporting from this module
just a simple string and it's now available inside my app.
js. Now they were able to get access to the exports from this module,
what if we wanted to get access to a function instead?
For example what if we wanted to be able to tap into this function?
Well if instead of setting our module.exports to equal hello world, we can set it to equal getDate.
Now the important thing with Javascript object is when you decide to add the parentheses because the
time when you add the parentheses then that means we're actually calling, we're activating the function
right?
And we don't want to do that inside our module because we want to allow the app.js to determine
when that function should be called.
So currently our date object here is bound to the exports of our date module and the exports of our date module
is simply just a function.
So if I were to log date as it is right now, you can see that it's only going to tell me that it's just
a function and it's called getDate.
It's not going to actually run that function and give me the return statement which is the actual date
that I'm looking for.
If I want it to run then I have to add my parentheses.
So now when I rerun my app.js you can see now it's running the function get date rather than just
logging the actual function.
Now by binding our exports to this function inside the module, we're now able to export it into our app.js
and we can use it anywhere we like.
So we don't have to activate it when we require it,
we can add it wherever it's needed.
So for example inside our app.get, we're now able to say date run or whatever is bound to that module
and let's say we save it inside something called day
right?
So now we have this thing called day which is bound to the output of this date module which currently
is getting us the current date because it's running this function getDate. What we're saying here
is we have this module called date and we're requiring it up here which binds all of the exports to this
constant called date. And then down here we call the function that's bound to that constant date and we
activate our getDate function. And now we have the result of it stored inside day which we're going
to pass over here.
Now we're able to head over to our console and run our app.j
js.
And now if we head over to our localhost:3000, you can see it's passing the output of that date module
into our title over here.
So we've managed to move our date code out of our app.js put it into its own separate module and
we're able to use it inside app.js or any other file for that matter.
And now this code in our date.js is completely reusable.
We can require it and use it anywhere we like.
But what if we wanted our date module to do more than one thing because at the moment all it exports
is just one function right?
It kind of makes its functionality quite limited.
What if we had say another function right? Down here. Let's say we had a function, instead of getdate
it's gets the day right?
The current day of the week. And pretty much all of this is the same
other than this option we only want the weekday to be in a long format and then we bind it to this thing
called day and we return it as the output of this function.
Now because our module.exports is only bound to getDate to function, we can't seem to access this
getDay.
How do we solve this?
Well if you remember previously I mentioned that module.export is a Javascript object.
And objects have properties and methods associated with it.
So that means that instead of simply binding the entire object to our getDate function, I could say module
.exports.geDate is equal to this function. And that means that I can do the same thing down
here and say model.exports.getDay is equal to the getDay function.
So now if at the end of all of this code we log our module.exports and we go back into our app.
.js and require that module,
then you can see that currently our exports object now has two functions that are tied to it.
One is called getDay and one is called getDate. Now inside our app.js, instead of saying just run
the function that's bound to the exports from our data module
we can say run the function that's bound to our date module .getDate.
And this will work exactly the same way as before
so I can restart my server and you can see that it's still working as expected
but now I have the option of saying, 'Oh maybe instead I just want the actual day of the week.'
So now if I go ahead and restart my server and refresh my website, you can see I'm using the getDay
function inside our date module to just bring up the actual day of the week.
This is how we can create our own modules and require them and get their functionality exported out of
the module to be used anywhere within our project.
So this makes it reusable and way more useful.
So this is the first step in our refactoring.
Now the next step is how can we make this a little bit more succinct?
How can we make it a bit shorter
because at the moment it's quite wordy
right?
So for example here where we're creating let day equals this and then return day, then we can simply
get rid of all of this and just say return this
right?
So we can now delete that and we can do the same over here.
We can simply just return that without having to bind it to another variable.
The next thing we can look at is for example here we're saying module.export.getDate equals
getDate function getDate this getDate-- like all over the place
right?
So how can we simplify this?
Well you might remember from earlier lessons that we mentioned that Javascript functions can be declared
in a variety of ways. And in the course resources a link to this particular blog post which does a really
good job of summarizing the 6 different ways that you can declare Javascript functions.
So there's a lot of different ways that you can do it.
Now the way that we're most used to is just a simple function declaration.
It's the function keyword, the name of the function, some inputs and maybe some outputs
right? Now another way of doing this is by using a function expression. We could set our function to equal
a variable instead.
And this means that we can pass our function around whenever we need it.
So now we have an anonymous function that's set to equal a variable with a name
and whenever we need that functionality we simply just refer to it by its name.
So let's implement it to understand it a bit better. Instead of having our getDate as a normal Javascript
function,
I'm going to change it into an anonymous function so this function doesn't have a name anymore. And instead
we're going to bind it to a variable that's called getDate.
And now this getDate variable is bound to our anonymous function.
And you can see now this is a little bit clearer.
Instead of saying module.exports.getDate = getDate which is basically the contents of
everything after the equal sign,
then we can simply delete all this and say module.exports.getDate is now equal to this anonymous
function.
And this means that we save on two get dates and we make everything a little bit more succinct.
Let's go ahead and do the same thing over here.
Let's delete this name of the function to turn it into an anonymous function
and we're simply going to set that function to equal module.exports.getDay.
Now we can make this even shorter by reading through our node.js documentation because if you scroll
down a little bit, you can see that node.js actually provides an export shortcut because just how often
it's used.
So instead of using module.exports we can simply just use the exports variable to refer to exactly
the same thing.
So here instead of saying module.exports, we can just say exports for short and it will refer to
the same thing which is module.exports.
So now let's hit save.
I'm going to delete this console log
and over here in my app.js I'm using date.getDate from my date module and I'm rendering it
as my list title.
So if we go ahead and launch our app now with nodemon to save ourselves the effort of restarting our
server all the time, then we can refresh and you can see our app works exactly the same.
Now while refactoring, we might as well try and refactor the rest of our code.
For example we've got a lot of let around here.
So these are variables but actually these variables are never going to vary.
So we can simply change it to const, const here as well
and const down here. Now because we're never really re-assigning the values of today or options, then
this won't change our code at all.
It still works exactly the same way.
Now back in our app.js we can do some more of that refactoring.
For example here where we're changing the items array into a const and you might say hey wait a minute,
what-- we're going to change this right? We're going to add new items to this array.
So how do we make it a constant?
Well this is a little bit of a quirk of Javascript and it's not this way in some languages
and it varies from language to language. But for Javascript at least, if you take a look at the MDN docs
for const and you scroll down at some of their examples, you can see that when they talk about arrays
when we create a constant which is an array, it's actually possible to push new items into the array.
But it's not possible to simply assign it to a brand new array.
This is one of the things that doesn't really stay constant.
The other thing that doesn't stay constant is when you have an object and you can't change that object
into an entirely new object
right?
This will throw an error because my object was declared as constant.
But if you try to change one of the values that's associated with one of the keys inside the object,
then you actually can
even though this thing is a constant.
So it's important to remember that when you declare something as constant in Javascript it's not protecting
the things that's inside that thing,
so inside the array or inside the object. You're still able to vary those things. You just can't assign
it to a new entirely different object or array.
So that means over here if we change all of those lets to consts, then it will still work just as well
and we won't actually come into any problems.
So let's hit save and nodemon's updating our server behind the scenes. And refresh our website
you can see that we're still getting the data here and we're still able to add items into our array
and cross them out as needed.
So I hope you enjoyed learning about EJS and templating with me in this module. In the next module we're
going to see if you can apply everything that we learned about EJS and templating into your very own
project.
So head over to the challenge once you're ready.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.