Reading from Files15:33 with Andrew Chalkley
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.
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 up