0:01 [Music] 0:08 Hey, what's going on guys? So, today 0:09 we're going to be building a full stack 0:11 real time polling application. And what 0:13 I mean by real time is there's no need 0:15 for refreshing the browser. You're going 0:17 to see the votes or the results as they 0:19 come in. And we're going to be using 0:21 canvas.js on the front end to display 0:24 the results in a chart. Now, we will be 0:26 using quite a few different 0:27 technologies. We'll build the backend 0:29 with NodeJS and express and we'll be 0:32 using a service or an API called pusher 0:35 for the real time subscriptions. 0:38 Basically, when a vote is submitted to 0:40 the server through the form, pusher is 0:42 going to trigger a response and it's 0:44 going to update the front end which will 0:46 be in vanilla JavaScript and it will 0:49 then we'll see we'll see that reflected 0:51 in the chart. All right. So, you could 0:54 use something like React or or Angular 0:56 in the front end, but this is a good 0:58 example of an application where you 1:00 don't need a front-end framework, okay? 1:02 Unless you're going to add a lot more 1:04 stuff to it. The way it is now, there's 1:06 really no need to add a framework. It 1:08 would just add bloat to the application. 1:10 Now, I'm going to break this up into at 1:13 least two videos, maybe more depending 1:15 on how long it takes. But first I want 1:17 to implement everything to make it a 1:20 real-time application where we'll be 1:22 able to submit votes and see them as 1:24 they come in. But when we re refresh the 1:27 page everything will go away in the 1:29 browser because the data won't be 1:31 persisted. All right. So once we get 1:33 that initial functionality then I want 1:36 to move on and add MongoDB and Mongoose 1:39 so that we can actually persist the 1:41 votes to a database. So when we enter 1:44 the application, we can see all the 1:46 votes that are already there. All right. 1:48 So if I were to reload this, you'll see 1:50 the votes are there because I already 1:52 have them persisted to the database. 1:54 Okay. So let me just give you a quick 1:56 demo. I have two tabs open and these are 1:59 basically two different clients. If this 2:01 was live, this could be somewhere in I 2:04 don't know Europe or and this could be 2:06 somewhere in Massachusetts in the US. 2:10 And if I were to vote, let's say Linux, 2:13 we'll give Linux some love and say vote, 2:16 it goes up from 3 to 4. And it also goes 2:20 up over here. So anyone viewing the 2:22 application is going to see that change 2:25 as well. They're not going to have to 2:26 reload their browser. Okay, which is a 2:29 very powerful thing. And you can see if 2:32 I go to MLAB, which is what we'll be 2:34 using for MongoDB, it's basically just a 2:37 remote database. You can see all 2:39 the different votes here. Okay. And each 2:41 vote has an ID. And ID is added by 2:44 default. And then it has an OS and 2:48 points. Okay. And we can change points 2:50 if we want, but I'm just going to leave 2:51 it set to one for each each vote. Okay. 2:56 So, let's see what else do we want to 2:58 look at. Pusher. Um Pusher is not 3:01 actually Let's go to the Pusher homepage 3:03 first. 3:05 So Pusher is not a polling service or 3:08 anything like that. Uh polling is just 3:10 what I chose to do with it. Uh but it's 3:12 just to it's just used to build real 3:14 time applications. Uh so chat chat 3:18 rooms, things like that is those are 3:20 good ideas uh for real time apps, data 3:23 analytics, stuff like that. And as far 3:26 as pricing goes, for free you'll get 100 3:29 max connections and 200,000 messages per 3:33 day. Okay, so a message is basically 3:36 just a like a subscription or a um uh a 3:40 triggered response from your server. In 3:43 our case, it'll be a vote. So 200,000 3:46 per day for free. If you were to deploy 3:48 this and make this a production 3:50 application that actually had traffic, 3:52 then you'd want to pay more, okay? or 3:54 you'd want to pay something. Um, just 3:57 like with any other service, same thing 3:59 with MLAB or Heroku. All of these 4:01 services, they give you a certain amount 4:03 of whether it's data or bandwidth or 4:07 requests, they give you a certain amount 4:09 and then once you pass that threshold, 4:11 you have to pay. Okay? So, it's great 4:13 for testing and learning and developing. 4:16 So, that's what we'll be building, guys. 4:18 Let's go ahead and get into it. Now, 4:20 you're going to want to create an 4:21 account with Pusher. It's completely 4:24 free to sign up. Uh you can sign up with 4:26 GitHub, which is what I did. And then 4:28 once you're signed up, you can go to 4:29 your dashboard. Now, I already have an 4:32 app created. So, you're looking at the 4:34 dashboard for that. And it shows you the 4:36 total messages, the total um connections 4:39 you've had for the day, stuff like that. 4:42 But I'm going to start from scratch 4:43 because I want you guys to be able to 4:45 follow along. So, I'm going to go to 4:47 your apps and create a new app. All 4:50 right. So, you should be following 4:52 along. if you want. Uh if not, just you 4:54 can just watch. But we're going to call 4:56 this push or pull. That's going to be 4:58 the name of the app. And then we can 5:00 choose our front-end technology. So we 5:02 can use Android, Angular, iOS, Backbone, 5:06 JavaScript, jQuery, or React. Okay, I'm 5:08 going to choose JavaScript. For the 5:10 backend tech, I'm going to choose 5:11 NodeJS. But as you can see, this is not 5:14 limited to JavaScript. You can use 5:16 Python, PHP, u even specific frameworks 5:20 like Django, Symphony. So it's it's very 5:23 powerful and very um diverse. 5:26 So right here you just it just asks you 5:28 what you're building. 5:31 I'll say real time polling app and 5:35 create. And there we go. So now we have 5:38 a new app created. This is our 5:39 dashboard. And then it gives you an 5:41 example of just a very barebones 5:45 implementation on the back end. We're 5:47 using nodes. So we want to install the 5:49 pusher module and then just initialize 5:52 it. You want to make sure you use your 5:54 own app data here, your ID and secret 5:56 key, all that stuff. And then when we 5:58 want to send a or trigger a response, we 6:01 use pusher.trigger. 6:03 And then on the front end, when we want 6:05 to catch it, we subscribe to it like 6:07 this. Pusher.subscribe. 6:10 Okay. Um, so we don't really have to do 6:12 anything else here. This is just our 6:14 dashboard. Uh, if we go to overview 6:17 again, you'll see all your connections 6:19 and stuff like that. But we can close 6:21 this up for now and get started with our 6:24 application. 6:25 Okay. So, what we're going to do is 6:27 create a new folder. 6:30 Uh, I'm going to create mine in my 6:32 Dropbox code prod. 6:35 And I'm going to create a new folder 6:36 here called 6:39 pusher pole. 6:41 And we're going to open that with VS 6:43 Code. You can use whatever text editor 6:45 you want, of course, but I'll be using 6:48 VS Code. I'll also be using the 6:50 integrated terminal, which if you hit 6:52 control or command back tick, that'll 6:54 open. I also have GitHub or Git Bash 6:57 integrated with my terminal here. All 7:00 right. So, let's go ahead and generate a 7:02 package.json JSON file with npm in it. 7:07 And we'll just go through this real 7:08 quick real quick. Description, I'll say 7:11 real time 7:14 polling app. And entry point, I'm going 7:17 to use app.js. 7:20 Let's see. Author, 7:22 feel free to put your own name. License, 7:25 I'm going to say MIT. Okay. But you can 7:27 put whatever you want. Doesn't really 7:29 matter. All right. Now, we need to 7:31 install some dependencies. 7:34 So, I'm going to clear this out and 7:35 we're going to do npmi or install. 7:39 We want express. We want body parser 7:42 because we're going to be handling a 7:44 form submission. We need to get the 7:46 data. So, body parser is used for that. 7:49 We also want pusher and we also want 7:52 cores because I want people from other 7:54 domains to make to be able to make 7:57 requests without having issues. All 7:59 right. So I think oh let's also add 8:03 mongoose. We won't be using it till 8:05 later but we might as well add it. So 8:07 those are the main dependencies. 8:11 Now we're going to install one more as a 8:13 dev dependency and that's nodemon so 8:15 that we can constantly watch our 8:17 application. So we'll say npmi-save-dev 8:23 to make it a dev dependency and then 8:25 nodemon. 8:29 Okay. And we're going to create two 8:30 scripts in our npm file as well or our 8:34 package.json file. So we can get rid of 8:37 this test and let's say start. So this 8:41 will be the main start script which will 8:43 be nodeapp.js. 8:46 So that's for like deployment your your 8:49 standard start. And then we'll do a dev 8:51 script which will use nodemon. So we'll 8:54 say nodemon app.js. 8:57 and nodemon will make it so that we 8:58 don't have to keep refreshing our 9:00 application our backend. So let's save 9:03 this and that should be good. Uh now 9:06 what we're going to do is create our 9:08 app.js file 9:11 and let's go ahead and open that up. 9:16 And we're going to start off just 9:18 building a basic express server. So 9:21 let's bring in express. 9:24 Uh, I'll say const express equals 9:26 require express. 9:30 And we might as well bring in some other 9:32 stuff as well. The path module is 9:34 included with Node.js. It's just to deal 9:37 with file paths. 9:39 We're going to use it to um to uh 9:43 declare the public folder. Now, for the 9:46 front end, you could build it anywhere. 9:48 I want to keep everything in the same 9:50 pusher pull folder. So, we'll be 9:53 building it inside the public directory, 9:55 but you don't have to. We enabled cores 9:57 and you'll be able to actually make 10:00 requests from anywhere. Um, so you don't 10:03 need to do that, but it's just for 10:04 simplicity. Okay? And we're not using 10:06 any kind of template engine or anything 10:08 like that. It's just going to be an HTML 10:10 file with some front-end JavaScript. 10:14 So we also need body parser 10:19 which again is for um getting the data 10:22 from our form 10:26 and we also want cores for cross domain 10:29 functionality 10:32 or authorization. 10:36 All right. Now what we'll do is create 10:39 our app variable and set it to express. 10:45 And next thing we'll do is let's set our 10:48 public folder. 10:52 So we do that by saying app do use 10:56 express.static. 10:59 And then in here we just want to 11:01 reference the folder we want to use. 11:03 Here we're going to use the path module 11:05 and the join method. And we're just 11:07 joining the current folder which is 11:10 undersc 11:11 durame. And then we want that we want 11:14 that to go to the public folder. All 11:18 right. So basically current directory 11:20 /public should be our static folder. 11:25 Now under that I'm just going to do the 11:27 body parser middleware. 11:31 This is just a couple lines that you 11:32 need to have if you're going to use the 11:34 body parser. Uh it's right in the 11:36 documentation as well. So it's going to 11:38 be app dot use 11:41 body parser.json. 11:45 And then we also want app dot use 11:49 body parser URL encoded. And we're going 11:52 to pass in an object with extended 11:56 and set that to false. All right. So 11:59 just standard middleware. 12:01 And then we want to enable cores. You 12:04 don't need the corores module for this, 12:06 but if you if you didn't use it, you'd 12:08 have to add the the code manually, which 12:10 is like I don't know, five or six lines 12:12 of code. By using the core the cores 12:15 module, we can just do app dot use and 12:19 then pass in cores like that. 12:23 All right. So, next thing we'll do is 12:25 create a port number. 12:29 I'll set that to 3000. And then we want 12:32 to be able to start the server. So we do 12:35 that with app.listen. 12:38 Pass in the port number. And we can put 12:40 a call back or an arrow function. And 12:43 then I'm just going to send a message to 12:45 the console that says 12:48 uh server started on port and I used 12:53 back ticks inside here. So we can use 12:55 this syntax for our variable. And that 12:59 should do it. So, we'll save it. And now 13:03 what I'm going to do is create the 13:04 public folder 13:07 and create an index html file. 13:11 Okay. Now, we're going to finish the 13:13 back end first, but I just want to make 13:15 sure that the the front end loads, the 13:17 index page loads. So, in this file, 13:19 let's use emit. We'll do exclamation 13:22 tab, which will give us our head body 13:24 tags. And inside the title here, let's 13:28 say 13:31 pusher pull. And then we'll put an H1 13:34 here. 13:37 And let's say OS vote. And that's it for 13:40 now. I just want to make sure this 13:42 loads. So we'll save this. And it should 13:45 load because it's index html and it's in 13:48 the public folder and we don't have a 13:50 specific route set in our app.js. So it 13:53 should work. So, let's go down here and 13:55 say npm rundev. 14:02 Uh, let's see. Oh, I already I have 14:04 something running on 3000. Let me just 14:07 cancel that real quick. 14:11 All right. So, let me see. Should work. 14:15 Oops. 14:19 Should work now hopefully. Yep. All 14:21 right. So, it's running on 3000. So, 14:23 let's open up a browser. 14:27 Uh, I'm just going to 14:30 go like that 14:33 and we'll go to localhost 3000. And 14:35 there we go. So, it's loading the index 14:37 html file from the public folder, which 14:40 is what we want. 14:42 So, like I said, we're going to do the 14:43 backend first, which isn't going to be 14:45 too difficult, especially um since we're 14:49 not implementing mongoose or anything 14:51 like that yet. Um, but what I want to do 14:53 is anything that has to do with pusher 14:56 or with our poll, I I want to put in a 14:58 separate file. So, we're going to use 14:59 the express router. So, what we'll do is 15:02 create a folder in the root called 15:05 routes. 15:07 And we're going to have a file in there 15:10 called pole.js. 15:13 Okay. And then let's go back to our 15:16 app.js file and let's include that. So 15:20 we'll just go right under 15:22 here and let's say const pole equals 15:28 require 15:31 and it's going to be dot slash it's in 15:33 the same fold it's in the same um root 15:36 directory and then in routes and then 15:39 pole. 15:40 Okay. And then to be able to use that 15:42 with the router, we're going to go down 15:44 to the bottom right before the port and 15:47 let's say const, I'm sorry, not const 15:50 app.use. 15:52 And we want to say anything that goes to 15:56 the slashpole URL 15:59 is going to um reflect in the poll file. 16:05 Okay, which we just set right here. 16:08 All right. So, we'll save that and then 16:10 we'll go to our pole.js. Now, it's going 16:12 to give us an error because it's telling 16:14 us um 16:17 yeah, we haven't set up the router yet. 16:19 So, let's go into pole.js. 16:22 And inside here, 16:24 what we'll do is first bring in express 16:26 because we need to use the express 16:28 router. 16:34 All right. And then we're going to 16:36 create our router. 16:38 So router equals express 16:42 dot router. 16:46 And let's go ahead and set up. We'll say 16:48 router.get 16:50 for the slash. Now since we're in the 16:53 pole routes file, when we do a slash, 16:56 that actually means if we go over here, 16:58 that actually means slashpole. 17:01 Okay? Because in the app.js, that's what 17:03 we set. Anything set to slpole will 17:06 reflect in the pole file and slash will 17:09 actually mean slpole. 17:11 So we'll put in our arrow function here. 17:14 And every route should have a request 17:17 and response passed in. 17:20 And then let's just put in here res. 17:24 And we'll just say I don't know poll. 17:28 And then if since we're using the router 17:30 we have to export it with 17:31 module.exports. exports 17:34 equals router 17:36 and save. And now let's go to slashpole 17:40 get request. And you can see we get that 17:43 sent to the browser. All right. So, uh 17:47 later on what will happen here is we'll 17:49 fetch from the database all of our polls 17:51 and we'll send a JSON response to the 17:53 front end. But for now, that's fine. 17:57 So when we submit our form, okay, so 18:00 this page will have a form and it's 18:02 going to make a post request to 18:04 slashpoll. So what we can do is say 18:07 router.post 18:09 to handle our post request. It's going 18:12 to be to slashpoll, but remember we're 18:13 in the polls route file. So it's just 18:15 going to be slash here. 18:20 And then we're going to just pass in 18:21 here request response. And then this is 18:26 where we actually want Whoops. We 18:27 actually want to trigger pusher. So if 18:30 we go back to our pusher 18:34 dashboard 18:38 uh which is here 18:41 and let's see is this the right 18:42 application? 18:44 No. All right. So if we go to our pusher 18:46 dashboard and we go to uh get started. 18:52 Let's go down here. We need to bring in 18:54 pusher. We need to initialize it with 18:57 our app data and then do the trigger 18:59 inside the post. Okay. So, let's bring 19:02 in pusher. 19:04 And we're in the pole.js file. 19:07 Uh let's see. So, const 19:10 pusher equals require 19:16 pusher. And then I'm going to grab this 19:18 here. Now, you'll have different app I 19:21 you'll have a different ID, key, secret, 19:23 all that stuff. Make sure you use your 19:25 own. Okay. And then I'm going to paste 19:27 that in there. And then for the trigger, 19:30 I guess I'll just go ahead and grab 19:32 that. 19:34 So, when the form submitted, it's going 19:35 to hit this route. And then we're going 19:38 to call pusher.trigger. 19:41 But we don't want to uh use my channel. 19:44 I'm not going to use that. 19:47 So, let's put in here OS-poll. 19:51 And then instead of my event, 19:54 let's use OS-vote. 19:57 And then we don't want to send a message 19:59 that says hello world. What we want to 20:02 send is the points and the actual vote 20:07 or the OS. 20:09 So, let's do 20:13 points. And I'm just going to put a one 20:16 here. And then the OS is going to come 20:20 from the form, which we can get from 20:21 request.body.Ooss. 20:24 Okay? Because we're using the body 20:26 parser. And then as far as what we're 20:28 going to return, it's just going to be a 20:31 JSON. We're going to say res.json. 20:34 And pass in here, we'll say success 20:38 true. And we'll put a message 20:42 which will be a string that says thank 20:44 you for voting. 20:49 All right. And that's it. So we'll save 20:52 that. 20:54 And up until we start to work with the 20:57 database, this should be it for the back 20:58 end. 21:00 Okay. So now what we'll do is in the 21:04 front end, the index html, 21:07 let's finish up the UI here, which is 21:09 pretty simple. 21:12 We do want to use materializs. 21:15 So I'm going to just go and search for 21:17 materialized css.com. Get started. And 21:20 we're going to grab the stylesheet, the 21:23 CDN here. And let's put that in the head 21:26 right there. And then the JavaScript, 21:29 we'll grab that script. Put that right 21:33 above the the ending body tag. Now, 21:35 materialize also needs jQuery. 21:39 So, I'm going to search for the jQuery 21:40 CDN. 21:42 And we're going to grab the uncompressed 21:44 version. Doesn't really matter. And just 21:47 grab the script tag. Make sure you put 21:49 it above the materialize. 21:52 Okay. So if we save that and we go back 21:55 to our front end, you can see that the 21:58 it's changed a little bit. Now I want to 22:00 wrap everything in a container. 22:04 All right. So we'll go ahead and bring 22:06 this H1. 22:08 Let's bring that up here. And then we're 22:10 going to put a paragraph. And we're just 22:12 going to say vote 22:16 for 22:18 your favorite 22:21 OS to 22:24 develop on. 22:26 And then we need some options. So we're 22:29 going to put in a form. I'm going to 22:31 give it an ID of let's say vote dash 22:35 form. And we don't need an action. Get 22:38 rid of that. 22:42 All right. And then inside the form, 22:44 let's put every every um radio button 22:47 inside a paragraph. I'm just going to 22:50 make this smaller, 22:53 actually. Let me make sure. Yeah. Okay. 22:55 So, everything's good on the back end. 22:57 So, inside the paragraph, we're going to 22:59 put an input, and we're going to give it 23:01 a type of radio. 23:04 And it's going to have a name. Let's 23:06 see. Name is going to be OS for all of 23:09 them. 23:10 ID for this one will be Windows and the 23:14 value for this will be Windows with a 23:17 capital W. All right. So underneath that 23:21 we want to have our label 23:24 which will be four windows. That should 23:26 match the ID of the input 23:28 and we'll say windows. All right. Let's 23:31 save it and see what it looks like so 23:33 far. Good. Um so now what I'll do is 23:36 take this paragraph. 23:38 Actually, just going to make this 23:40 smaller. So, we'll take this paragraph 23:42 and we'll just go ahead and copy that 23:44 down three more times. So, it should be 23:47 four total. And let's change the ID here 23:52 to MacOSS. 23:55 Change the value 23:57 to MacOSS 24:04 that 24:11 this one here will be Linux. 24:20 Value should be uppercase. That's what's 24:22 actually going to be put in the 24:24 database. 24:25 Uh let's see 24:28 let's just say Linux distro 24:33 meaning that whether they're using 24:35 Abuntu or or Mint or anything they can 24:38 choose this option 24:41 and then the last one will be other. 24:51 All right. And for the text, I'm just 24:53 going to say something else. 24:57 Four should be other. All right. So, 24:59 those are our options. Now, let's put in 25:01 an input with the type of submit. And 25:04 the value will be vote. 25:07 And let's give it a class of btn to make 25:10 it look good. And save. Reload. And 25:13 there we go. There's our form. Now, as 25:16 far as the HTML, the only other thing we 25:18 need is a container for the chart. So, 25:20 I'm going to go below the form and just 25:24 put in a couple line breaks. 25:27 And then under that, I'm going to have a 25:29 div with the id of chart 25:33 container. 25:35 And uh we're also going to give it a 25:38 style. 25:41 And that will be a height of 300 pixels. 25:46 Oops, 300 pixels. And then let's do a 25:49 width of 100%. 25:53 So 100%. 25:55 And that should be good. Okay. So that 25:57 that's where our chart will go. 25:59 Nothing's going to show up yet because 26:01 we we have to initialize it in the 26:03 JavaScript. 26:05 Now there's a couple things we need to 26:07 add here in our scripts. We need to add 26:09 the CDN for canvas.js 26:12 as well as the CDN for Pusher on the 26:14 front end. All right. So, we're going to 26:17 search for 26:19 pusher CDN. 26:21 And this first option here from CDNJS, 26:25 we'll grab 26:28 uh right here, pusher min.js. I'm going 26:30 to copy the script tag. And we're going 26:33 to put that right under the materialize 26:36 script. And then let's also search 26:40 for canvas.js 26:44 CDN. 26:47 and we're going to grab the canvas min 26:50 script tag and put that right here. 26:54 Okay. And then we're going to have our 26:56 own JavaScript file on the front end as 26:58 well. So let's put in script source and 27:02 we'll call it main.js. 27:05 So let's save that and let's create that 27:07 file. So in public we need a main.js 27:12 file. All right. All right. And this is 27:14 where all of our Java our client side 27:16 JavaScript is going to go. 27:19 Now, this video is getting kind of long, 27:21 so I think I'm going to go ahead and 27:22 stop it here. Um, now that we have our 27:25 backend pretty much done until we're 27:27 we're dealing with the database, and 27:29 then our frontend UI is done, all of our 27:31 scripts are connected, now we just want 27:33 to write our client side JavaScript. So, 27:35 we'll do that in the next