WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:02.400 [MUSIC PLAYING] 00:00:05.847 --> 00:00:08.430 DOUG LLOYD: So as you continue your exploration of JavaScript, 00:00:08.430 --> 00:00:10.304 there's one other technique that really might 00:00:10.304 --> 00:00:13.530 come in handy as you begin to build more complex websites, 00:00:13.530 --> 00:00:16.890 and that is using something called Ajax. 00:00:16.890 --> 00:00:20.031 So, so far, in our exploration of JavaScript, 00:00:20.031 --> 00:00:22.530 we've been limited to doing a couple of really simple things 00:00:22.530 --> 00:00:24.510 for the purpose of illustration, like you click a button, 00:00:24.510 --> 00:00:25.426 and something happens. 00:00:25.426 --> 00:00:29.040 Maybe the color changes on your site, or maybe a couple of words change. 00:00:29.040 --> 00:00:32.479 But the catch is everything we've been doing so far has been client side. 00:00:32.479 --> 00:00:34.170 It's all happening on our computer. 00:00:34.170 --> 00:00:37.050 We're never really talking to the outside world. 00:00:37.050 --> 00:00:41.190 We can, however, talk to the outside world and make changes on our website, 00:00:41.190 --> 00:00:44.320 have something happen that interact with the server, 00:00:44.320 --> 00:00:46.305 but maybe it doesn't reload our entire page. 00:00:46.305 --> 00:00:49.200 We want to create a more pleasant user experience. 00:00:49.200 --> 00:00:51.390 Ajax allows us to do that. 00:00:51.390 --> 00:00:54.870 Ajax used to stand for something called Asynchronous JavaScript in XML. 00:00:54.870 --> 00:00:56.180 That's a backronym. 00:00:56.180 --> 00:00:58.710 That's not really what it's called anymore. 00:00:58.710 --> 00:01:03.120 And actually, most commonly now, instead of XML, we use JSON. 00:01:03.120 --> 00:01:07.200 But Ajax has just been the name that's kind of stuck for the technique. 00:01:07.200 --> 00:01:11.130 And what Ajax allows us to do is to refresh, basically, sections 00:01:11.130 --> 00:01:13.220 of our page without the entire page. 00:01:13.220 --> 00:01:17.260 And if you're, for example, somebody who follows sports, for instance, 00:01:17.260 --> 00:01:21.030 you might see this if you're on a sports website 00:01:21.030 --> 00:01:24.760 where scores of games that are going on currently are being updated, 00:01:24.760 --> 00:01:26.460 but the whole page doesn't refresh. 00:01:26.460 --> 00:01:29.400 That means that the page is basically taking advantage of Ajax 00:01:29.400 --> 00:01:32.880 to just update small portions of the page. 00:01:32.880 --> 00:01:36.005 The techniques that you can do with Ajax are pretty limitless. 00:01:36.005 --> 00:01:37.880 You can do a lot of different things with it. 00:01:37.880 --> 00:01:40.200 And we're going to focus on a very specific example where, again, we're 00:01:40.200 --> 00:01:42.480 clicking a button, and something happens. 00:01:42.480 --> 00:01:45.821 But the difference is this time when something happens, 00:01:45.821 --> 00:01:47.070 we're making a server request. 00:01:47.070 --> 00:01:49.050 We're making an outbound request from a page. 00:01:49.050 --> 00:01:51.970 It's not just happening on our machine. 00:01:51.970 --> 00:01:56.200 But you can do things like updating, for example, 00:01:56.200 --> 00:02:00.360 the sports scores on a website that tracks that information or your email. 00:02:00.360 --> 00:02:03.300 You might notice that sometimes when you get a new email, 00:02:03.300 --> 00:02:05.894 your entire body of your page refreshes to put 00:02:05.894 --> 00:02:09.060 that new email at the top of your inbox, but the whole page doesn't refresh. 00:02:09.060 --> 00:02:10.710 That's happening with Ajax as well. 00:02:10.710 --> 00:02:13.339 But it's constantly running all the time. 00:02:13.339 --> 00:02:14.880 It's just basically querying forever. 00:02:14.880 --> 00:02:17.713 We're, again, just going to focus on clicking a button and something 00:02:17.713 --> 00:02:22.110 happening, but that something being not just local to our machine anymore. 00:02:22.110 --> 00:02:24.060 So, in order to do this, we have to create 00:02:24.060 --> 00:02:28.860 another special kind of JavaScript object called an XMLHttpRequest. 00:02:28.860 --> 00:02:31.500 And what this does is it allows us to make it 00:02:31.500 --> 00:02:35.592 asynchronous, so not at the same time as the refresh of the page 00:02:35.592 --> 00:02:38.800 or loading the page, but sometime there after while we still are on the page. 00:02:38.800 --> 00:02:40.940 That's what we mean when we say asynchronous. 00:02:40.940 --> 00:02:43.950 it allows us to make an asynchronous request 00:02:43.950 --> 00:02:45.954 to a server to get more information. 00:02:45.954 --> 00:02:48.120 It's actually very easy to create this, fortunately. 00:02:48.120 --> 00:02:52.440 This line for example would create a new x amount HTTP request object. 00:02:52.440 --> 00:02:55.230 And in this case, I'm just calling that xhttp, 00:02:55.230 --> 00:03:00.450 and assigning it to just a random, local variable in JavaScript. 00:03:00.450 --> 00:03:03.720 Once you have the object, so once you've created it, 00:03:03.720 --> 00:03:09.480 the first thing you have to do is define an onreadystatechange behavior. 00:03:09.480 --> 00:03:13.650 Onreadystatechange is really just a wordy way 00:03:13.650 --> 00:03:17.290 to describe the steps that are happening when you visit a page. 00:03:17.290 --> 00:03:20.640 So, for example, you click on-- 00:03:20.640 --> 00:03:21.510 you're on a page. 00:03:21.510 --> 00:03:22.410 You refresh the page. 00:03:22.410 --> 00:03:24.951 It sort of all goes blank for a second, then some of the data 00:03:24.951 --> 00:03:25.782 starts to populate. 00:03:25.782 --> 00:03:27.990 And then it stops refreshing, and you're ready to go. 00:03:27.990 --> 00:03:30.073 That's going through a series of different states, 00:03:30.073 --> 00:03:33.510 where it goes from the request hasn't been initiated to your sending 00:03:33.510 --> 00:03:37.004 the request to the request is received to the request is on its way 00:03:37.004 --> 00:03:38.920 back to you, and then the request is complete. 00:03:38.920 --> 00:03:41.460 Those are, for example, a couple of different state changes 00:03:41.460 --> 00:03:43.950 that might take place when you're visiting a site. 00:03:43.950 --> 00:03:45.930 And it will also be the kinds of state changes 00:03:45.930 --> 00:03:47.638 that will take place when you're updating 00:03:47.638 --> 00:03:50.070 a smaller section of your site. 00:03:50.070 --> 00:03:52.515 Typically, we define something that is supposed 00:03:52.515 --> 00:03:55.140 to happen when the state change is using an anonymous function. 00:03:55.140 --> 00:03:58.400 And we're going to see an example of this in just a moment. 00:03:58.400 --> 00:03:59.370 We don't have to give that function a name, 00:03:59.370 --> 00:04:01.161 we just want it to do something whenever it 00:04:01.161 --> 00:04:06.370 detects some change in the status of loading the site. 00:04:06.370 --> 00:04:09.420 There are five different states. 00:04:09.420 --> 00:04:10.680 They go from 0 to 4. 00:04:10.680 --> 00:04:14.210 That is the readyState property, so that's part of the onreadystate change. 00:04:14.210 --> 00:04:15.603 It's clearly related. 00:04:15.603 --> 00:04:17.519 And those are what I basically just described, 00:04:17.519 --> 00:04:19.644 where 0 is the request has not yet been initialized 00:04:19.644 --> 00:04:22.170 and, 4, which is the end, which is the ultimate goal 00:04:22.170 --> 00:04:27.300 of a an onreadystate state change request or an Ajax request 00:04:27.300 --> 00:04:29.580 is to get that readyState to 4, which basically 00:04:29.580 --> 00:04:31.290 means the entire them has loaded. 00:04:31.290 --> 00:04:33.965 And hopefully, the status that we get back is 200. 00:04:33.965 --> 00:04:36.090 Those are the two things we're really caring about. 00:04:36.090 --> 00:04:39.420 We want to make sure that when our Ajax request is completed, 00:04:39.420 --> 00:04:42.750 that the readyState is 4, so the data has been received, 00:04:42.750 --> 00:04:44.760 and the data was received OK. 00:04:44.760 --> 00:04:49.800 You may recall 200 being the HTTP code for OK. 00:04:49.800 --> 00:04:51.870 That was the one we, fortunately, never saw. 00:04:51.870 --> 00:04:55.240 We didn't go to a website and get a-- you don't go to website and get a 200, 00:04:55.240 --> 00:04:57.725 like you get a 404, for example. 00:04:57.725 --> 00:04:59.850 So we want, ultimately, for the readyState to be 4, 00:04:59.850 --> 00:05:01.410 and the status to be 200. 00:05:01.410 --> 00:05:05.980 When that's the case, we can then update our site. 00:05:05.980 --> 00:05:10.167 Once we have that, we just need to open the request and send the request. 00:05:10.167 --> 00:05:11.500 And then, our site will refresh. 00:05:11.500 --> 00:05:13.120 Again, we're going to see a very concrete example 00:05:13.120 --> 00:05:14.420 of this in just a minute. 00:05:14.420 --> 00:05:16.270 So if it doesn't make sense just now, hopefully, it 00:05:16.270 --> 00:05:18.103 will when we start to see some code, and you 00:05:18.103 --> 00:05:23.020 see how that interaction takes place for real on a website. 00:05:23.020 --> 00:05:25.780 There is, I want to point out again, a very slightly different way 00:05:25.780 --> 00:05:27.820 to do this syntactically using jQuery. 00:05:27.820 --> 00:05:30.880 And, in fact, you will very commonly see nowadays 00:05:30.880 --> 00:05:34.270 Ajax requests made using jQuery. 00:05:34.270 --> 00:05:37.900 We're explicitly showing you the pure JavaScript version of this 00:05:37.900 --> 00:05:38.950 just so you see it. 00:05:38.950 --> 00:05:42.220 But as you become more comfortable using jQuery for client-side scripting, 00:05:42.220 --> 00:05:45.640 for example, for using DOM manipulation or for Ajax request, 00:05:45.640 --> 00:05:50.510 you'll probably see the syntax of this slightly differently. 00:05:50.510 --> 00:05:55.000 So here is a JavaScript function that is preparing, opening, 00:05:55.000 --> 00:05:57.580 and sending an Ajax request. 00:05:57.580 --> 00:06:00.779 So the first thing I would do is I'd create my new XMLHttpRequest, 00:06:00.779 --> 00:06:03.070 and I'm going to, again, assigned to a random variable, 00:06:03.070 --> 00:06:05.830 this time called aj for Ajax. 00:06:05.830 --> 00:06:08.710 Then, I'm going to define a function that is going 00:06:08.710 --> 00:06:11.850 to execute on the readyState changing. 00:06:11.850 --> 00:06:15.241 So every time the readyState changes, this function will execute. 00:06:15.241 --> 00:06:16.990 But as you can see, it's only really going 00:06:16.990 --> 00:06:22.080 to do something, eventually, once the readyState is 4, and the status is 200. 00:06:22.080 --> 00:06:24.760 So it's going to-- 00:06:24.760 --> 00:06:27.880 this function will get executed every time the state changes, 00:06:27.880 --> 00:06:33.880 but it's only going to have a meaningful thing to do once the readyState is 4, 00:06:33.880 --> 00:06:35.230 and the status is 200. 00:06:35.230 --> 00:06:37.810 And we'll see a concrete example of that in a second 00:06:37.810 --> 00:06:40.180 where we're going to be updating a section of our site 00:06:40.180 --> 00:06:43.420 with different photos and information. 00:06:43.420 --> 00:06:51.090 Once that is done, we're then going to open our XML requests or Ajax request. 00:06:51.090 --> 00:06:53.380 This is just a simple way to do this. 00:06:53.380 --> 00:06:57.527 We're basically creating a GET request of a particular URL. 00:06:57.527 --> 00:06:59.110 Don't worry about what the true means. 00:06:59.110 --> 00:07:02.080 And then, we're just going to send that request. 00:07:02.080 --> 00:07:08.140 So, again, you'll usually see this written in jQuery, instead of 00:07:08.140 --> 00:07:10.314 in pure JavaScript. 00:07:10.314 --> 00:07:12.730 So if you want to learn a little bit about how to do that, 00:07:12.730 --> 00:07:14.830 you can take a look at this URL here. 00:07:14.830 --> 00:07:19.690 But for now, let's head into the IDE and see this example in action, 00:07:19.690 --> 00:07:22.030 making Ajax requests of a server, where the server 00:07:22.030 --> 00:07:24.502 happens to be running locally on my machine, 00:07:24.502 --> 00:07:26.460 to see how we can change a page asynchronously. 00:07:26.460 --> 00:07:30.250 So if you download the source code that comes with this short 00:07:30.250 --> 00:07:34.330 and you open up the index.html within there, 00:07:34.330 --> 00:07:37.060 you'll find a page that looks like this called Ajax test. 00:07:37.060 --> 00:07:40.167 There's a dropdown menu in the section that says Information Goes Here. 00:07:40.167 --> 00:07:41.750 We'll see what that means in a second. 00:07:41.750 --> 00:07:42.580 I'm not going to tinker with that yet. 00:07:42.580 --> 00:07:45.330 I want to show you what's behind the scenes before we take a look. 00:07:45.330 --> 00:07:47.850 So here is the source code for that. 00:07:47.850 --> 00:07:49.600 At the top here, I'm just loading a couple 00:07:49.600 --> 00:07:50.950 of [? scripts. ?] I'm loading jQuery because I 00:07:50.950 --> 00:07:53.116 will use a little bit of jQuery in this as well just 00:07:53.116 --> 00:07:54.760 to give you a little taste of it. 00:07:54.760 --> 00:08:00.070 I have my own JavaScript scripts that I wrote called Ajax.js we're 00:08:00.070 --> 00:08:02.060 going to take a look at just a second. 00:08:02.060 --> 00:08:03.820 You'll see that the information goes here 00:08:03.820 --> 00:08:11.230 that we were just looking at on the site is in a div whose ID is infodiv. 00:08:11.230 --> 00:08:13.610 That will be really important in just a minute. 00:08:13.610 --> 00:08:17.380 And then I have a form where I have a couple of different options. 00:08:17.380 --> 00:08:21.730 And when something happens, particularly when the value changes, 00:08:21.730 --> 00:08:24.910 when I select a different options from the list, 00:08:24.910 --> 00:08:28.330 I'm going to call this function, cs50info 00:08:28.330 --> 00:08:31.840 and then I pass in the parameter this.value. 00:08:31.840 --> 00:08:33.850 You may recall from our video on JavaScript 00:08:33.850 --> 00:08:39.370 that this is a way to self-refer to the event that 00:08:39.370 --> 00:08:44.910 triggered the JavaScript function being called in the first place. 00:08:44.910 --> 00:08:48.820 So this is another form of an event handler as opposed to on click, 00:08:48.820 --> 00:08:50.071 it's on change. 00:08:50.071 --> 00:08:51.820 And what this is going to do is it's going 00:08:51.820 --> 00:08:56.725 to allow me to figure out which one of the options triggered the change. 00:08:56.725 --> 00:09:02.170 And I'm going to capture this.value, so this is what I mean with value, 00:09:02.170 --> 00:09:04.580 is I'm going to get this piece of information. 00:09:04.580 --> 00:09:07.000 So if I choose Rob Bowden from this list, 00:09:07.000 --> 00:09:09.036 basically, I'm passing in CS50 info. 00:09:09.036 --> 00:09:12.160 And then, the value that actually gets passed into that function is bowden. 00:09:12.160 --> 00:09:15.730 They're all in lowercase-- chan, [? mailand, ?] and [? zaclova. ?] So 00:09:15.730 --> 00:09:20.150 those are the different things that will be passed into that CS50 info function. 00:09:20.150 --> 00:09:22.000 What does that CS50 info function do? 00:09:22.000 --> 00:09:24.610 Well, let's take a look at Ajax.js. 00:09:24.610 --> 00:09:29.555 Here's CS50 info, if the name is empty, so if I didn't choose one of the actual 00:09:29.555 --> 00:09:31.930 options, if I just choose the default option at the top-- 00:09:31.930 --> 00:09:33.670 you might be familiar with this from using dropdowns, 00:09:33.670 --> 00:09:36.330 where there's a blank thing and you have to actually pick something-- 00:09:36.330 --> 00:09:36.710 I return. 00:09:36.710 --> 00:09:37.543 I don't do anything. 00:09:37.543 --> 00:09:39.640 I don't want to try and do anything fancy. 00:09:39.640 --> 00:09:42.850 Otherwise, I create an XMLHttpRequest. 00:09:42.850 --> 00:09:45.730 We just saw this in the slides a moment ago. 00:09:45.730 --> 00:09:49.010 And I define a function that is going to wait for the readyState to be 4, 00:09:49.010 --> 00:09:51.070 and the status to be 200. 00:09:51.070 --> 00:09:54.730 And when it does, when it's there, what do I want to do? 00:09:54.730 --> 00:09:59.650 I want to update the HTML inside of the infodiv. 00:09:59.650 --> 00:10:01.410 This is the jQuery way to describe this. 00:10:01.410 --> 00:10:03.951 This is the line of jQuery that you're going to see in this-- 00:10:03.951 --> 00:10:06.160 the rest of it is JavaScript, this is jQuery-- 00:10:06.160 --> 00:10:10.200 to whatever I get back from my Ajax request. 00:10:10.200 --> 00:10:12.700 Remember, I haven't made the Ajax request entirely just yet. 00:10:12.700 --> 00:10:15.850 That's going to be right down here with the open and send. 00:10:15.850 --> 00:10:17.830 But when I do, I'm going to get data back, 00:10:17.830 --> 00:10:22.330 and I'm going to update whatever the HTML of infodiv, which at the beginning 00:10:22.330 --> 00:10:26.420 was information goes here-- that was what was in between the div tags. 00:10:26.420 --> 00:10:29.567 I'm going to to change that to whatever I get back in my request. 00:10:29.567 --> 00:10:31.900 But I'm going to do it without updating the entire page. 00:10:31.900 --> 00:10:35.500 I'm going to refresh, so to speak, just that div, 00:10:35.500 --> 00:10:38.668 just that section of the page. 00:10:38.668 --> 00:10:40.600 So what file am I opening? 00:10:40.600 --> 00:10:44.520 Well, I'm sending a GET request for name plus .HTML. 00:10:44.520 --> 00:10:47.950 Remember, that name is just the name of the value, the variable that's 00:10:47.950 --> 00:10:49.450 being passed in as a parameter here. 00:10:49.450 --> 00:10:50.860 So that's what name is. 00:10:50.860 --> 00:10:56.350 So name is going to be bowden or chan, [? mailand, ?] or [? zaclova. ?] And 00:10:56.350 --> 00:10:58.810 apparently, I'm going to add .HTML at the end of it. 00:10:58.810 --> 00:10:59.890 Well, what does one of these look like? 00:10:59.890 --> 00:11:02.150 Well, it looks like just kind of a snippet of HTML. 00:11:02.150 --> 00:11:06.480 It's clearly not entirely correct HTML because I don't have 00:11:06.480 --> 00:11:08.236 HTML tags on the top and bottom of it. 00:11:08.236 --> 00:11:09.610 I don't have body tags around it. 00:11:09.610 --> 00:11:12.030 But it's some little bit of HTML. 00:11:12.030 --> 00:11:15.460 It has a paragraph with a name, an image tag, 00:11:15.460 --> 00:11:19.670 and a couple of other paragraphs with some information. 00:11:19.670 --> 00:11:22.940 So let's see this actually in action and see what it does. 00:11:22.940 --> 00:11:24.760 So right now, I have Ajax tests. 00:11:24.760 --> 00:11:27.970 And remember, when I choose an option, that function 00:11:27.970 --> 00:11:31.180 is going to execute that CS50 info function passing in whatever one 00:11:31.180 --> 00:11:32.020 I choose. 00:11:32.020 --> 00:11:35.196 So let's choose Zamyla. 00:11:35.196 --> 00:11:36.320 So notice what it did here. 00:11:36.320 --> 00:11:39.150 It popped in all of that information from our page. 00:11:39.150 --> 00:11:41.020 There's that Zamyla tag. 00:11:41.020 --> 00:11:43.310 So I'll pop back to the ID for a second. 00:11:43.310 --> 00:11:47.940 We have a paragraph with her name, an image, class of 2014, 00:11:47.940 --> 00:11:49.260 and Winthrop House. 00:11:49.260 --> 00:11:52.287 Indeed, all of that information is now here. 00:11:52.287 --> 00:11:53.620 But what happens if I change it? 00:11:53.620 --> 00:11:56.170 I don't want my entire page to refresh, but I do 00:11:56.170 --> 00:11:58.610 want the content of that div to change. 00:11:58.610 --> 00:12:01.110 So let's try and switch it to, for example, Rob. 00:12:01.110 --> 00:12:03.068 And if you look really carefully, and depending 00:12:03.068 --> 00:12:05.230 on if my computer is a little bit slower or faster, 00:12:05.230 --> 00:12:10.480 you might quickly see all of the content get deleted and then replaced. 00:12:10.480 --> 00:12:14.240 That is the asynchronous request happening very quickly. 00:12:14.240 --> 00:12:16.660 So let's see if we can see it. 00:12:16.660 --> 00:12:20.486 You might have noticed right there that everything deleted and then everything 00:12:20.486 --> 00:12:22.360 came back, but now, I have new data because I 00:12:22.360 --> 00:12:25.000 chose a new option from the list. 00:12:25.000 --> 00:12:27.570 Remember if I choose Select Someone, nothing happens. 00:12:27.570 --> 00:12:29.650 I returned immediately, so it doesn't go back 00:12:29.650 --> 00:12:32.440 to information goes here, although I could have written 00:12:32.440 --> 00:12:34.930 the function differently to do that. 00:12:34.930 --> 00:12:37.440 But I can just make these different asynchronous requests, 00:12:37.440 --> 00:12:40.480 and it's going to keep updating the information that I see on the page 00:12:40.480 --> 00:12:46.520 without refreshing the entire page, just the section that I care about. 00:12:46.520 --> 00:12:47.570 So this is pretty cool. 00:12:47.570 --> 00:12:49.990 Now, we can, not only change things locally 00:12:49.990 --> 00:12:52.660 on our machine, simple things like colors, 00:12:52.660 --> 00:12:55.304 but we can also now send outbound requests to servers. 00:12:55.304 --> 00:12:57.970 And they don't even have to be servers that are running locally. 00:12:57.970 --> 00:13:01.150 I could be maybe sourcing information from Yahoo Finance 00:13:01.150 --> 00:13:04.330 if I want to pull data from Yahoo Finance asynchronously. 00:13:04.330 --> 00:13:06.519 Maybe I'll do that and load that into my page 00:13:06.519 --> 00:13:08.560 and have that be some information that constantly 00:13:08.560 --> 00:13:11.560 gets updated because maybe I have a different way of displaying the data 00:13:11.560 --> 00:13:12.110 or something. 00:13:12.110 --> 00:13:17.110 So it's an interesting new strategy that we have at our disposal. 00:13:17.110 --> 00:13:18.520 We can send requests locally. 00:13:18.520 --> 00:13:21.610 We can send requests outbound to other servers 00:13:21.610 --> 00:13:27.020 and really take advantage of creating a better user experience using Ajax. 00:13:27.020 --> 00:13:28.270 I'm Doug Lloyd. 00:13:28.270 --> 00:13:30.220 This is CS50.