Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
The basis of our templates are the contents of the files in our views folder. We'll need to use Node.js' File System module to read the contents of our files.
Node.js APIs Used
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
Now that we have our templates, let's read
these files and
0:00
then send the contents of those files in
the response.
0:02
So remember in our app JS file we said
that we were going
0:07
to create a function that handles the
reading of files and match the values in.
0:12
We're gonna read from the file.
0:17
And then merge, merge the values in.
0:18
Well, we're not gonna do that here in the
app JS file.
0:20
It's just too much of a disconnect of what
this app is.
0:24
The app should just be like, okay, bump.
0:28
This sets up the server, we're done.
0:30
We do all the routing in the router JS
file.
0:32
And in turn, we should probably move this
into its own file as well.
0:36
So, let's create a new file called
renderer.js
0:41
because we want to render our templates to
the response.
0:47
So I'm just gonna paste those comments in
there just
0:54
to keep it fresh in our mind what we're
going to do, and
0:58
let's start with creating a function
called view.
1:03
[BLANK_AUDIO]
1:08
Now what do we want to do in here?
1:17
We want to read from the template files.
1:18
And we want to insert values into the
content.
1:29
And we want to write out to the response.
1:37
And let's just get rid of that.
1:45
Because that's basically what we said
there.
1:46
And, in order to do that, we need a couple
of parameters to, to do this.
1:49
We need the template name, the values, and
the response server.
1:56
We need the template name to read from the
template.
2:00
We need the values to put into the
contents of that file.
2:02
And then we need to write out to the
response.
2:06
So, template name
2:09
[BLANK_AUDIO]
2:11
Values and response.
2:16
So, how do we read from a file?
2:21
Let's take a look at the documentation on
the node.js website.
2:24
So, Docs, API Docs, and then file system.
2:30
Let's scroll down
2:35
to read file.
2:41
There we go.
2:46
Read file.
2:47
That looks like what we want to use.
2:48
This is fs.readFile and then a path, and
then as a function with an error.
2:50
So you can throw the error and you can log
the data throw out.
2:57
So let's try this out.
3:01
So let's copy and paste this.
3:04
Copy and then paste here.
3:05
[BLANK_AUDIO]
3:09
Let's just indent this correctly.
3:15
And we want to do this in the callback.
3:18
And we've got a variable that we haven't
used yet.
3:24
We need to actually require the module
3:27
var fs is equal to require fs.
3:33
Which is short for file system.
3:37
And if you don't know how to do that,
3:41
you just scroll up to the top of these
documentation pages.
3:42
And they generally do show you how to
import the module.
3:45
So here for example it shows you how to do
it.
3:50
So, not on every example are you gonna see
the requirement of it.
3:55
You just assume because you've seen it at
the top of
4:00
the part of the documentation that you're
in that you just know when you,
4:03
when you're further down the page that's
how you import it.
4:08
So, I would prefer it if they included it
in every code sample just for
4:12
completeness.
4:16
But what can you do?
4:17
So, instead of using this code that they
have given us, let's make it our own.
4:21
So, we want it to go and read a file in a
particular path.
4:25
And that's the views path.
4:29
So let's do that.
4:32
So .views, and then another slash.
4:33
And then, instead of us passing the
template name with .html at the end,
4:39
let's just pass in the name that's
different.
4:44
And, and we can automatically
programmatically add .html to the end,
4:47
so we could do something like this.
4:52
So we could do template name plus
4:55
[BLANK_AUDIO]
4:58
.html.
5:00
[BLANK_AUDIO]
5:01
And then let's say this is an error.
5:04
And this is actually the file contents,
and
5:07
let's just do error and error.
5:13
And instead of console.log we've got a
response, so
5:18
let's just do response.write.
5:23
[BLANK_AUDIO]
5:26
File contents.
5:30
So, we should be able to now write the
file contents from
5:32
our template by passing in parameters to
this method,
5:37
the view method, and we can write out the
content to the response.
5:42
So let's export that
5:48
module.exports.view is equal to view,
5:53
and go to our router.
6:03
And in here we can import var renderer,
require.
6:07
[BLANK_AUDIO]
6:15
And then the path to our renderer.
6:20
[BLANK_AUDIO]
6:21
I've just noticed I've spelt renderer
wrong, so let's just put an n in there.
6:29
And down here, let's do renderer.view.
6:34
And remember, it was template name was the
first parameter.
6:40
So let's do header, all in lowercase this
time.
6:43
[BLANK_AUDIO]
6:47
And then the values.
6:51
There's no values we want to put in that.
6:52
There's nothing that we need.
6:53
And then we want to pass in the response.
6:55
And, let's try that out.
6:59
[BLANK_AUDIO]
7:02
Let's start up our application, and
7:10
go to the preview and for some reason.
7:14
We're getting a search and footer, we
don't have the header.
7:19
Now, does that mean our code's not working
or is there something else going on here?
7:24
Well, if we go back to our renderer, you
7:29
see we've put this in a call back, so it
takes some time to actually
7:35
go through the disc and read information
off it and then write it to the response.
7:40
And then by that time this line has been
executed and this line has been executed.
7:44
So we've been loading the files from the
disc asynchronously.
7:50
So in this case we want to actually read
the file synchronously.
7:55
I, we wait for it to read the file and
then read the next file and
8:01
then read the next file.
8:04
And it doesn't take that long and what,
you maybe be thinking, well,
8:06
isn't node supposed to be this
non-blocking.
8:10
Well, there's sometimes where you want it
to block and
8:13
sometimes where you don't want it to
block.
8:16
So, so for example, we're doing three
separate operations here.
8:17
We're writing the header to the response
and then the app will wait to
8:21
write the search to the response and then
the app will again and do the footer.
8:28
But, it's already been writing to the
response.
8:33
So the browser's already getting all that
information.
8:35
So, in the header if you were linking to a
CSS file that's external.
8:38
It can be starting to download that, the
browser,
8:43
whilst your server is still writing out
the search to the, to the response.
8:47
So, it, it works out pretty well to do it
like this anyway.
8:52
So, let's take a look back at the
documentation to see if there's a sync
8:57
sync version.
9:03
So if we go to readFileSync, it's the
synchronous ver, version of read file.
9:05
And it returns the con, contents of the
file then.
9:12
And if the encoding option is specified,
then the function will return a string,
9:15
otherwise its a buffer.
9:20
Again.
9:21
So, let's just go back to our code, and
let's change this to readFileSync.
9:22
And we don't need to callback because it's
synchronous this time.
9:33
And let's set the variable as
fileContents.
9:37
And get rid of that, end of that callback.
9:46
[BLANK_AUDIO]
9:49
So now, we read from the file.
9:52
We actually do need to still insert,
9:59
values in to the content.
10:04
And then we need to write out the contents
to the response.
10:08
Okay.
10:18
So we're not waiting for a callback now.
10:19
When it goes through this, it should block
and then do this, and then do this.
10:22
So let's try it out.
10:26
[BLANK_AUDIO]
10:28
So we have the DOCTYPE html, and
everything that's in the header,
10:37
which is up to the body.
10:41
And then we've got the search and footer.
10:43
So now we can see it actually working,
reading from the files and
10:45
printed out to the response.
10:48
Let's do that with all of our responses
now.
10:50
So, renderer.view.
10:53
We can do the search, and
10:57
it's gonna be empty and a response.
11:04
And then, we want that for the footer as
well.
11:10
[BLANK_AUDIO]
11:13
And again for the header.
11:17
[BLANK_AUDIO]
11:19
So we can do that for the header as well
on the user profile page,
11:27
and then we've got this, so instead of it
saying search, we can say profile.
11:33
And these values are actually the values
we
11:42
want to pass in to the template this time.
11:45
So, instead of having a blank object of
values we want the actual
11:50
values of the response from the GSM
profile.
11:54
And renderer.view for the footer.
12:00
And we don't need to put in any values for
the footer.
12:06
And the same goes for the error page, and
we wanna do error.
12:12
And remember we had a variable called
errorMessage, and
12:20
that can be the error.message.
12:25
So remember the error has a prop, property
called message.
12:31
So we're accessing the error message and
12:36
we're setting it as this value, which
eventually we'll put into here.
12:39
[BLANK_AUDIO]
12:44
And on the error page we also still want
to search.
12:48
So, if you, say, can't find another user,
we can still search again.
12:51
So I'm just gonna copy that search line.
12:56
You can type it in if you want, but copy
and paste works for me.
12:59
And pop that there.
13:02
So, the composition of the user profile
page is the header,
13:04
then the profile information and then the
footer.
13:11
Need to spell footer right.
13:12
[BLANK_AUDIO]
13:15
And then if errors is the composition is
the header, which is up here.
13:19
And then in the error callback, we've got
the error with the error message,
13:26
we've got the search, and then we've got
the footer.
13:29
And the composition of the homepage is the
header, the search and the footer.
13:32
There's no dynamic content in that.
13:36
So, let's try that out one more time.
13:40
[BLANK_AUDIO]
13:43
When we go to the home route, we see the
header and
13:47
we see the body, and we see the search
form, and the footer.
13:52
Let's do chalkers.
13:58
[BLANK_AUDIO]
14:00
So we've got all this here, and it goes
body and profile and body,
14:03
but if you notice, this, this still going
around because we haven't ended
14:08
the request on all of our things, so let's
do that now before we forget.
14:12
So, we want to just do response.end,
14:17
and we can do that up here as well for the
home route.
14:26
And we want to do that on our error.
14:33
So we want to give an indication to the
browser that
14:37
there's no more information coming that is
all done.
14:40
So let's just try that one more time.
14:43
[BLANK_AUDIO]
14:45
So this is the homepage, and as you can
see it's not doing that anymore.
14:50
And let's go to chalkers.
14:54
[BLANK_AUDIO]
14:57
And as you can see, it shows all the
avatar URL, the user name,
15:02
badges and, and points.
15:07
And let's go to an error page.
15:10
And as you can see the header is still the
same,
15:15
but in here we've got the error message.
15:17
And the search form again, so we can
search for
15:20
another user name if we get it incorrect.
15:24
So there we have it.
15:27
We've got our views being read from the
file system and
15:27
then put into the response.
15:30
Cool.
15:33
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up