- [Instructor] One of the main places that closures
can be used in JavaScript is to create modules.
The idea of a module is to encapsulate a set of code
and expose just a subset of properties
and methods for working with it.
A module keeps some values totally protected while providing
access to others in specific ways through its methods.
Another advantage of using a module
is that it avoids polluting the global namespace.
All methods and properties are replaced with a single name,
the name of the module.
The code to create a module returns an object.
The methods within that returned object contain closures
and the code that returns the object uses an IIFE
so it's invoked immediately
when the JavaScript code is parsed.
The return value is assigned to a variable.
You can then access the methods of the returned object
using the name of the variable,
which becomes the name of the module.
In the code for this video,
in addition to the function at the top
of the script.js file,
we have a number of variables and a few functions
further down in the code.
I'm going to leave the code at the top alone.
This is what logs events.
If we were putting more work into this app,
we'd probably want to abstract that into another file
so we could use it in different pages and apps.
So starting here on line 14,
I'm going to add a new variable called list widget,
and I'll use const,
and this is going to store the object
that will make up the module.
So the value of this variable is going to be an IIFE.
And so I'll start my IIFE, paren function,
empty parens and then an opening curly brace.
I'm going to take out that closing syntax
and starting on line 15,
I'm going to go all the way down to line 89.
I'm going to indent all that just inside of the IIFE
and then add a new line on 90.
I'm going to close my function.
I'm going to close my IIFE
and then I'm going to add an additional set of parens
at the end to invoke that function
and a semi-colon to finish it all off.
So that creates the IIFE.
And now I need to actually export
some properties and methods.
And so examining my code,
I have a few properties and methods
that need to be accessed outside of the module.
The URL and the API key are accessed outside of the module
and the event listeners,
but the activities and the state
and the category variables are not,
they're only accessed inside the module
so they don't need to be exported.
And then all three functions within the module
needs to be exported as well.
So I'm simply going to create a return statement
and set its value to an object that includes the code
for the variables and functions I want to export.
And so I'm going to add a new line
after the category variable,
simply going to be a return statement
and the value to return is going to be an object.
So I'll take out that closing curly brace for the object.
And then again,
I'm going to indent lines 26 all the way through 90.
And then after line 90, add one more new line,
close my object, add an ending semi-colon.
And now I notice I have some red squigglies
and that's because I need to convert the contents
of the object to use object notation
instead of variable names.
So here in 26, instead of using a let keyword,
I need to use a colon
and replace that semi-colon with a comma.
And then the same thing for API key.
For update activity list.
And update activity lists starts on line 28.
Can follow that indent all the way down to line 67,
where I need to put a comma.
And then again, with update UI success, colon function,
and follow that down to line 87 comma,
and then finally update UI failure.
Colon function, that ends on line 90.
We're all good, the red squiggles are gone,
and then I need to do one final thing.
All five of these properties and methods
are now keys within the list widget object.
So I need to change all the references outside of the module
to reference the object name first.
So first down here in the fetch code in line 99,
we've got the URL and that should reference
listwidget.url, and I'm going to copy list widget dot.
So I also need to add that prefix
to the reference to the API key,
and then also the update UI success method
of the list widget object and the update UI failure method.
And then in the next event listener,
there's a reference to update activity list
where I need to add that list widget prefix,
and then up above in the code for update UI success,
I have a referenced update activity list,
and I'm going to change that reference
to use the name of the object as well.
And so saving my changes.
I'm going to reload this in my browser.
Type Tokyo, click get forecast, and it works.
And all I'm looking for here is that the activity list
functionality works because the module code
didn't touch that logging function from the top.
So I get a successful API response.
If I click these buttons, my dom manipulation works.
So I've got the same functionality,
but I've done two things.
I've taken variables and function names
out of the global namespace and I've also organized my code.