back to indexAngularJS end-to-end web app tutorial Part I
Chapters
0:0
0:3 creating a web application
4:12 display the details of an existing one
15:41 run the server
27:11 create an index dot html
34:11 writing some code
38:29 add an input tags
49:19 use a filter in your html
00:00:00.000 |
So today I'm going to be demonstrating creating a web application and it's a pretty standard 00:00:08.440 |
kind of web application which we'd call a CRUD application. 00:00:11.120 |
We can talk more about that in a moment but basically something that's capable of listing, 00:00:15.880 |
displaying, changing, updating and deleting stuff. 00:00:20.160 |
For some reason whenever people demonstrate creating CRUD applications it's always a to-do 00:00:26.680 |
list so we are not going to be any different and we are going to create a to-do list. 00:00:30.380 |
But it's interesting to think about, for example, what if you're creating an email application. 00:00:35.240 |
You're basically listing, displaying, creating, deleting emails, for example. 00:00:41.120 |
So you know, CRUD applications are pretty widely applicable and the stuff that we'll 00:00:45.800 |
be seeing today, you know, it's flexible enough I think you'd be able to use it quite widely. 00:00:54.560 |
I'm going to be showing a particular set of tools. 00:01:02.400 |
So there's a back-end part and we'll talk about what that is in a moment with the stuff 00:01:06.800 |
that runs on the server and that'll be written in C# and WebAPI with SQL Server and Entity 00:01:14.600 |
That whole section is like, you can replace that with anything you like really, really 00:01:18.080 |
easily and I'll be showing how to replace it with Python and SQLite today in fact because 00:01:25.480 |
that bit's like very, very fast, very, very simple, doesn't do very, very much at all. 00:01:31.640 |
The interesting part is all at the front end, the stuff that runs in your browser and I'll 00:01:35.560 |
be showing how to use a framework called AngularJS which is a framework that comes out of Google 00:01:41.080 |
and it's quite mature because they've been using it at Google for quite a while. 00:01:46.840 |
It's a very sophisticated and very complete framework to make it really easy to write 00:01:56.240 |
It's a bit of a learning curve and the documentation is very complete at the moment but it's not 00:02:02.600 |
as friendly as it could be so hopefully this tutorial will fill in a gap around getting 00:02:09.840 |
I'll also show how to make it look like not totally awful by stealing styles from Bootstrap. 00:02:16.920 |
I don't know if you guys have seen Bootstrap before but it's something that came out of 00:02:20.560 |
a couple of guys at Twitter so basically make it really fast and easy to make your websites 00:02:26.200 |
I'm not going to spend any time making it look any good but just slightly unsucky but 00:02:35.360 |
the nice thing about Bootstrap is again it's very flexible and so it's very easy to make 00:02:40.840 |
You can even download themes and make it look as nice as you like and I'm actually going 00:02:45.520 |
to make this end to end which means I'm actually going to get this website up and running on 00:02:50.920 |
a public facing server that anybody can access because that's a piece that people often miss 00:02:56.640 |
and I want to show you how easy even that is because it's no good if it's just running 00:03:04.120 |
Just get straight into it unless anybody has any questions. 00:03:08.560 |
We're going to start with the back end and let's first of all have a look at what it 00:03:14.960 |
Here is the finished product as you can see it is a to-do list and it basically can do 00:03:24.360 |
a number of things so let's try and enumerate what those are. 00:03:33.800 |
It's going to be able to list to-dos and then within that we want to be able to search through 00:03:43.640 |
them, we want to be able to sort them, we want to be able to paginate them. 00:03:47.360 |
In other words if there's lots and lots of them we don't want to just download the entire 00:03:51.120 |
set at once but rather be able to download a page at a time. 00:03:56.760 |
Then we need to be able to edit a to-do that already exists or create a new one and also 00:04:06.840 |
If we change these words slightly to oh and also we want to be able to display the details 00:04:16.680 |
So if we change these slightly to retrieve and change the order slightly so we're going 00:04:23.360 |
to create retrieve and instead of edit we'll call that update. 00:04:26.760 |
You will now see we have CRUD so this is why this is called a CRUD application. 00:04:33.880 |
The retrieve fit is both a single one and also a list of them. 00:04:39.960 |
The way we're going to do this is let me draw this actually is we're going to have you've 00:04:45.960 |
got like your browser over here and your browser only really knows how to run one kind of 00:04:56.240 |
It knows how to display stuff that's written in HTML and it knows how to display it by 00:05:04.880 |
So we're going to use JavaScript to do all the heavy listing but we actually need, behind 00:05:10.520 |
the scenes obviously these things are going to have to be stored somewhere, they're going 00:05:13.640 |
to be stored in a database so that's going to store a whole bunch of to-dos. 00:05:19.400 |
And then something needs to be able to connect up the database to your browser, in other 00:05:23.880 |
words make those database functions available to your browser and the way we do that is 00:05:32.960 |
So REST is basically something that allows JavaScript to talk to our server through standard 00:05:39.840 |
HTTP and in particular HTTP provides a number of different things, it provides something 00:05:48.000 |
This is the thing that normally your web browser uses to display web pages. 00:05:52.520 |
It has something called POST which is the thing that your browser normally uses to like 00:05:56.440 |
upload files or submit forms or stuff like that. 00:05:59.960 |
It also has something called DELETE and it also has something called PUT. 00:06:11.000 |
Those last two generally your browser does not make available to you but they do exist 00:06:14.680 |
behind the scenes and if you look they actually correspond quite nicely to the CRUD thing. 00:06:23.160 |
So we've got a create which is actually POST, we've got a retrieve which is actually GET, 00:06:29.560 |
we've got DELETE already and we've got an update which is actually PUT. 00:06:34.240 |
So all REST does is it basically provides something accessible from JavaScript that 00:06:39.840 |
maps each of these HTTP verbs into each of the CRUD things to run against the database. 00:06:48.440 |
So GET would for example get turned into a select statement using SQL, POST would get 00:06:55.240 |
turned into an insert statement, DELETE would get turned into a delete statement and PUT 00:07:12.840 |
So the proportion of websites that do something that is not CRUD, well I guess you would say 00:07:19.720 |
the majority of websites do things that are not CRUD because they often just display things. 00:07:28.280 |
But in a sense the way they display them often behind the scenes is using CRUD. 00:07:33.200 |
So take a blog, most of the time when you're looking at blog posts you're basically doing 00:07:40.840 |
a retrieve of a list and behind the scenes of course somebody's got to be creating, deleting 00:07:44.920 |
and updating those so I suppose a blog is a good example of CRUD. 00:07:48.840 |
An example of something that would not be a good example of CRUD would be something 00:07:53.240 |
like an HTML5 game for example or people create things like colour pickers or stuff like that. 00:08:08.280 |
So Kaggle.com certainly has plenty of CRUD types in it, you have to be able to create 00:08:13.720 |
competitions, delete competitions, update competitions, list competitions, create competitions, 00:08:24.720 |
Yeah, a good proportion of the world's websites have multiple CRUD pieces going on in them. 00:08:34.920 |
So for example in an email app you have CRUD for emails, for contacts, for folders and 00:08:41.680 |
each of these things you need somewhere to create them, list them, delete them, change 00:08:47.900 |
So because this is so common this is something that is really easy to do. 00:08:54.840 |
And so what we need to do is we basically, if you think about what's the minimum necessary 00:09:00.920 |
that we could possibly have to tell a computer, we would at least have to tell a computer 00:09:05.620 |
like what is my, we'll call it a CRUD object, what's the thing which I'm actually trying 00:09:13.840 |
to create, delete and so forth and when I say what is it, what I really mean is what 00:09:25.360 |
And that's I think really all we ought to have to tell the computer what are its properties, 00:09:31.000 |
oh and I guess we have to call it like what is it called, in our case it will be called 00:09:40.520 |
So that's actually what we're going to start by doing and this is where we're going to 00:09:45.520 |
do it on the server because this is kind of where the database is going to be built and 00:09:50.440 |
where this API is going to have to be provided from. 00:09:54.260 |
So this is where I'm going to start with Visual Studio which is a really nice IDE for creating 00:10:00.400 |
a variety of applications including applications of this kind, they call them web applications. 00:10:08.420 |
So let's create one, we'll call it angular tutorial. 00:10:24.960 |
And so we say here we want to create a web application using the latest version of the 00:10:29.200 |
framework that Microsoft have which is called ASP.NET MVC and then it says alright what 00:10:34.760 |
kind do you want and I want to use web API which basically means I'm creating this really 00:10:39.120 |
minimum kind of interface for it, can't quite see the bottom of this so let's move this 00:10:46.680 |
Oh that's really annoying, let's try to double clicking that, there we go. 00:10:55.240 |
So now that's creating the project, let's go and see what we do next. 00:11:00.960 |
So here's, that's what we've done, we've selected the project, there's some, here we go, so are 00:11:13.400 |
we ready yet, I'm still creating, this is my blog. 00:11:30.840 |
There's a, the API which it creates for you can use either JSON which is JavaScript object 00:11:41.060 |
notation or XML which is perhaps more common in big culprits in a slightly older format. 00:11:47.640 |
By default the API uses XML unless you specifically ask otherwise so there's actually just a couple 00:11:55.040 |
of lines that I'm going to copy and paste to tell it to use JSON by default instead. 00:12:01.320 |
It's totally unnecessary but I just find it nice because it makes it easy to debug it 00:12:05.720 |
by actually viewing the JSON so let's do that if it's finished. 00:12:12.280 |
So I have to go into web API config, web API config and register so I'm just going to paste 00:12:23.040 |
it there, so that's totally unimportant in that section but it's in our list so now we're 00:12:28.960 |
ready to create this minimum amount of information that we should have to tell the server which 00:12:34.520 |
is what is the object that we're trying to actually create and the way you do that pretty 00:12:38.960 |
much regardless of what language you're doing is you create a class for it. 00:12:44.800 |
So generally speaking there will be something called models or something like that, whatever 00:12:49.240 |
language you're using and then we can just create a new one by just creating a class. 00:12:59.720 |
So we'll call ours todo so the first thing we have to do is tell it what is the name 00:13:04.200 |
of the object so we've now called it, given it a name and the next thing we have to do 00:13:09.040 |
is we have to tell it what are its properties so we're certainly going to need an ID, we're 00:13:26.280 |
going to need the actual text of the todo so should we call that text maybe? 00:13:47.760 |
Question mark in C# means it's nullable, in other words you don't have to fill it out. 00:13:53.480 |
What else did I have in my list, oh priority that's a good idea, so let's also add priority. 00:14:02.440 |
Okay so at this point we have now told what I believe is everything that our computer 00:14:12.640 |
should need to know in order to create our web API for us so at this point we're going 00:14:17.520 |
to tell it to create a web API for us so in C# the way you do that is by creating something 00:14:22.960 |
called a controller and we will call this todo controller and it 00:14:36.480 |
is a API controller so in other words it's going to create one of those JSON APIs or 00:14:42.640 |
REST APIs, it's going to create it for our todo class and we need to have it create all 00:14:50.760 |
the database stuff for us so we'll ask it to do so, we'll click add, we'll wait for 00:15:00.480 |
a few moments and while that's running, yeah so I will show you that once it's done. 00:15:12.480 |
It looks like it's finished, you can see it's created something called todo controller, 00:15:19.080 |
you can see it's created also something called todo context which consists of like two lines 00:15:30.320 |
of code and we're at a point now where I'm going to hit F5 to run this or you can go 00:15:36.840 |
debug start debugging and that will build it and run the server and we should be now 00:15:53.040 |
Now it will even tell us where the API is and as you can see here it's got, it's going 00:16:00.440 |
to be API slash todo so let's try going to API slash todo. 00:16:15.560 |
You can think about what you expect this to return while we're waiting for it. 00:16:23.360 |
The first time that you go to it, it kind of has to compile a few things in the background 00:16:30.220 |
and so hopefully you guys had guessed that it was going to return an empty array in JSON 00:16:35.040 |
and so that means it's returned square brackets. 00:16:39.400 |
So we now have a working API and Anthony to ask your question about what's happened behind 00:16:59.760 |
And you'll see that behind the scenes it has automatically created, this is one I did earlier, 00:17:05.920 |
here's today's date, a database for us and within that database it has already automatically 00:17:18.520 |
Even the way it's todo is by adding an E and within that table we'll see that it has automatically 00:17:33.580 |
created our columns for us once eventually that runs. 00:17:50.000 |
JSON is easier for a human to read, it's more compact, it's simpler to both create and understand. 00:18:02.520 |
The question would be why would you use XML over JSON really? 00:18:06.600 |
Also JSON, it's very easy for computers to parse as well, so it tends to be very fast 00:18:17.080 |
Here's the columns that we've created and again automatically they've been typed and 00:18:21.080 |
so forth, our date is nullable because we asked it to be, our priority is not and so 00:18:27.800 |
So you can see everything automatically has happened behind the scenes to create our database, 00:18:31.440 |
to create our web API and that is why I say don't worry too much about the backend, it's 00:18:39.040 |
I'm now going to show you the Python version, I'm not actually going to type it in, I'm just 00:18:44.400 |
In Python, I've used here something called Flask Restless, which is kind of like a web 00:18:52.960 |
You basically tell it what kind of database you want to use, in this case I've said use 00:18:58.440 |
SQLite, you then create your class, you then create the fields in your class, I've actually 00:19:04.400 |
got a few extra fields in here just for playing, and then you don't actually have to like right 00:19:10.320 |
click something and say create framework, instead you simply say manager.create API, 00:19:17.040 |
you tell it what class you want to create a JSON API for, you tell it what methods you 00:19:21.440 |
want to support, you tell it by default how many results you want per page and you say 00:19:26.440 |
app.run and that provides exactly, basically nearly exactly the same API as I just described. 00:19:33.040 |
So as you can see Python and C# really require you to type pretty much the exact same code. 00:19:39.640 |
The big benefit to the C# version is that the code, it's created for me, I can go and 00:19:45.280 |
edit to change later, or else the Flask Restless version, it's all pre-programmed in. 00:19:51.400 |
Although of course you can use Flask to create your own API endpoints, but really the main 00:19:56.960 |
message is here, don't worry about the back end. 00:20:00.600 |
Again even in the Python version db.create all, make sure that the database gets created, 00:20:04.880 |
creates a table, creates a field, so on and so forth. 00:20:10.840 |
And the nice thing is like the debugging, you can always go back and actually type in 00:20:17.400 |
your endpoints and actually watch them work, so in case something doesn't happen you can 00:20:31.200 |
Yeah you can post queries through the browser in a wide variety of ways. 00:20:36.620 |
In Windows there's something called Fiddler which makes it really easy to hand create 00:20:39.840 |
your own HTTP requests basically of any kind. 00:20:45.960 |
It's going to be easier to write our application if there's already some data in it. 00:20:49.820 |
So generally speaking when you're doing an application like this you want to do something 00:20:54.800 |
This is again something that's going to be specific on what back end you're using. 00:21:02.080 |
In Visual Studio it's really nice and easy, there's basically a console that's available 00:21:06.040 |
to you, a REPL that's available to you to let you do that. 00:21:09.720 |
So you can basically go package manager console and there's a system called migrations which 00:21:20.520 |
is a system that on the back end allows you to do things like database updates, seeding 00:21:34.040 |
Turn the scenes to those who are interested, this is actually a PowerShell prompt that's 00:21:39.320 |
actually sitting here inside Visual Studio with access to all these Visual Studio objects. 00:21:47.120 |
So that's created this thing called the seed method which we can now use to fill it with 00:21:55.080 |
So I'm not going to manually type that in, let's just copy and paste it. 00:21:59.620 |
So this particular version is just going to use a random number generator. 00:22:34.000 |
I'm just creating a whole bunch of items, I'm creating 50 of them with a due date which 00:22:40.040 |
is randomly in last year and a priority which is some random number up to 10 and the text 00:22:48.800 |
So this will just give us some data which makes life a little bit easier to start playing 00:22:55.160 |
And so the other reason I wanted to show you this is basically to show you how easy it 00:23:01.380 |
So although the database got created automatically, it's very easy for us to edit the database 00:23:09.440 |
So now that we've made this change to our database, in this case a change to the initial 00:23:14.480 |
data that's in it, you just have to run a command to tell it to actually make that change 00:23:20.360 |
Not surprisingly, the command is update database. 00:23:30.480 |
And it's quite amazing, if we go back and change this class to add a field or make something 00:23:37.960 |
nullable or change a data type, and we can then basically, it will automatically create 00:23:42.680 |
the C# code necessarily to actually change the database so it actually keeps track of 00:23:46.840 |
what the current class is and what it used to look like and so forth, which I think is 00:23:53.640 |
Well, it actually, this particular version is, but it actually originally came from Ruby. 00:23:59.560 |
So the idea of migrations, I don't know if it's first came from Ruby, but that's the 00:24:05.800 |
So now that we've done that, let's try rerunning our API. 00:24:11.760 |
And you can think about what you would expect to appear, there we go, already done. 00:24:22.760 |
So that is the entire backend, so now we need to start writing our frontend. 00:24:37.200 |
So we're gonna use Bootstrap and we're gonna use AngularJS, neither of them is installed 00:24:43.240 |
into Visual Studio by default, not surprisingly. 00:24:47.960 |
Most systems will have some easy way to install packages. 00:24:52.480 |
In Visual Studio, that system is called NuGet, you probably won't be surprised to hear that 00:24:57.760 |
you use the console here, and you just type install package and the name of the package. 00:25:07.280 |
So we're gonna need AngularJS, so this is the thing that's gonna handle all of the connecting 00:25:14.000 |
up that JSON API to our actual web page, so you can actually see what's going on. 00:25:22.500 |
And what that does behind the scenes is it downloads it and it installs it into our solution. 00:25:29.240 |
So you can actually see what that looks like. 00:25:38.800 |
So you can see that there's, here they are, all appearing now as we watch. 00:25:42.680 |
So it automatically unpacks it, puts it into the right place, so the scripts are already 00:25:48.080 |
been placed into scripts for us, and if there was any CSS, input into CSS, it looks like 00:26:00.640 |
There's a GUI for all this as well if you want to use one, but I kind of like typing 00:26:11.280 |
because I find it a little bit quicker and a little bit more auditable. 00:26:15.000 |
So now we can check what that looks like, yep, there we go, all the CSS has already been 00:26:20.240 |
put in here for us, along with any necessary images. 00:26:25.360 |
So that's kind of nice, we've got everything downloaded and installed and ready to go. 00:26:32.200 |
That's right, so jQuery is automatically installed by the web API, when we first said I want 00:26:41.480 |
to use web API they installed a few things for us, the main one they installed was jQuery. 00:26:49.760 |
No you don't, in fact it's installed jQuery through the same system, which means that 00:26:55.240 |
for example if I later use something that requires a higher version of jQuery it will 00:26:59.920 |
automatically upgrade it and do everything for me. 00:27:04.960 |
All that we've done so far is to kind of download those files and put them in the right place. 00:27:11.120 |
The next thing we have to do is create an index.html that actually does something with 00:27:32.780 |
Now the index.html that Angular expects to see has a very specific format, in fact it's 00:27:39.040 |
so specific that I've created a ReSharper template for it, so let's do that, ng-index. 00:27:49.840 |
So I need to tell it what the name of this application is and what the title will be, 00:27:57.600 |
Angular.js.tutorial.todo.app and that is my index.html, so basically every index.html for 00:28:09.120 |
Angular will look exactly the same, the only thing that will look different really is which 00:28:13.380 |
style sheets and scripts do you stick in here. 00:28:19.400 |
ReSharper is specific to Visual Studio but whatever IDE you use will have some kind of 00:28:24.760 |
insert a template or insert commonly used text or something like that. 00:28:28.720 |
If it doesn't stick scripts like this into little text documents, you can copy and post 00:28:33.640 |
them as required, no point typing it again and again or you can just copy and paste it 00:28:40.680 |
As it says here, all you have to do is change the ng-app attribute and the title. 00:28:49.840 |
So we're now up to talking about some conceptual stuff which is what's going on here because 00:28:55.300 |
literally this is going to be the start and the end of index.html, we're not going to 00:29:01.280 |
So what we're instead going to do is we're going to create things called details.html, 00:29:06.080 |
list.html and so forth and we're going to let Angular figure out how to do all that. 00:29:12.440 |
So what I'm going to do is slightly weird, I'm going to first of all show you the code, 00:29:17.480 |
we're not going to really understand what the code is and then I'm going to come back 00:29:22.760 |
I just want to first give you a sense of what code we need. 00:29:26.560 |
The first thing we need is we're going to need to create our own JavaScript file which 00:29:31.400 |
is like where we can put our own code into and in Angular generally that JavaScript file 00:29:36.200 |
is called app.js so that's why my template already has something referring to app.js. 00:29:50.680 |
So in app.js there's a very standard thing you need which is you basically have to have 00:29:58.480 |
this little Angular application constructor so again as you can see this is a very sharp 00:30:03.320 |
template, it's totally standard code even if it looks slightly hairy at this stage so 00:30:09.280 |
I need to give it a name and I need to describe basically what's the thing that happens when 00:30:17.480 |
You can see this here so we need to do a list. 00:30:22.000 |
Let's try that again, sorry, gaptodo list and let's have a file list.html. 00:30:40.360 |
Let me explain what's going on here, this is a bit where in fact this is where I'm going 00:30:43.760 |
to flick across and start drawing some stuff so what I want to point out is that we have 00:30:50.400 |
told Angular exactly two things or three things actually, when you go to some path what controller 00:30:56.800 |
do you use, what template do you use, so there are three things I want to explain what's 00:31:01.800 |
going on there because that's really what this is all about so this next bit is going 00:31:10.900 |
So the way Angular works is or in fact if you think about it the way your browser works 00:31:15.400 |
is that your browser has requested index.html or at least we will shortly. 00:31:24.800 |
And in it there's basically a number of JavaScript libraries referred to and behind the scenes 00:31:29.560 |
what happens if you refer to a JavaScript library it just takes that code and it runs 00:31:36.960 |
And one of the things in there was the Angular JavaScript and one of the things in there was 00:31:51.080 |
The other thing you might have noticed is there was something, let's have a look at 00:31:59.240 |
it in fact, there was something called ng-view and there was also something called ng-app. 00:32:16.000 |
What happens as soon as Angular loads and once the whole HTML file is loaded Angular 00:32:26.840 |
goes back over your HTML and looks to see if it can find something called ng-app and 00:32:32.520 |
if it does it says okay this is an Angular application, I'm going to create an Angular 00:32:37.120 |
application called todo-app and I'm going to try and see if anybody has created some 00:32:44.840 |
And to do that we have actually created, this is how you tell it, that this code is for 00:32:52.040 |
So you can see this text here matches this text here. 00:32:56.760 |
So now the JavaScript and the HTML have been connected together, Angular knows that these 00:33:03.040 |
two files are designed to work together and so now that it knows that it reads to find 00:33:10.760 |
out how to configure this application and so it then says okay, in particular I want 00:33:16.960 |
to know when you go somewhere what code will I be using and how will I be displaying it. 00:33:26.200 |
So you've got index.html which via app.js tells it two things. 00:33:33.520 |
One is what code should I run for a particular path and what page should I show. 00:33:46.200 |
This is called the controller and this is called the template. 00:33:57.600 |
So this will become more clear as we do a few, but anybody who has used MVC before will 00:34:02.560 |
be very familiar with all of this, basically every MVC framework in the world works pretty 00:34:15.680 |
In this case we need to create our controller and we're going to create something which 00:34:24.080 |
Now I'm going to explain exactly what's going on here in a moment, but I've just got a pretty 00:34:31.720 |
minimal controller which is creating something called test and setting a particular value. 00:34:35.600 |
And the second thing I need to do is create something called list.html. 00:34:51.800 |
And because this is now a template it's going to be inserted into the spot where this says 00:34:57.120 |
ng-view which means that it already has an html tag, a head tag, a body tag and so forth. 00:35:02.720 |
So we can delete everything else and just type what we want. 00:35:08.080 |
So let's go hello and we're going to now insert something from our JavaScript. 00:35:16.920 |
So we've got something in JavaScript called test and the way you do that is by putting 00:35:21.800 |
it in these things called handlebars, double angle brackets. 00:35:25.280 |
So this is going to be like, I'm going to explain exactly what's going on in a moment, 00:35:29.600 |
but I just wanted to show you this really minimum version of tying HTML and JavaScript 00:35:35.200 |
So let's save all that and see what happens when we go to that page. 00:35:54.080 |
So index.html, remember, has only that in it, but Angular then checked app.js, looking to 00:36:07.280 |
see if it can find something with this same application name, it found it and then recognized 00:36:13.360 |
that then when you're in the root of this, I should get code from the list controller, 00:36:23.000 |
And then the template says, what should you display? 00:36:27.160 |
So the really cool thing which we need to understand clearly is what is test and what 00:36:39.160 |
So that's the thing that I'm going to explain now. 00:36:50.480 |
Inside your controller, something is made automatically available and that something 00:36:58.520 |
It's a JavaScript object with very, very special properties, so very, very special behaviors. 00:37:05.640 |
The way it works is that anything that's inside dollar scope is automatically bound to the 00:37:17.080 |
HTML page, so anything that you put inside dollar scope is automatically made available 00:37:23.320 |
in the HTML and you can then refer to it in the HTML by putting it in those handlebar 00:37:32.480 |
Now, in the HTML, you don't need to say dollar scope dot because this is a very definition 00:37:39.760 |
It's something that comes out of dollar scope. 00:37:43.760 |
It's so neat that literally as soon as you change something in the controller, it changes 00:37:48.800 |
in real time in the page and there's actually two ways of making it appear in the page. 00:37:55.120 |
One is by putting it in just regular text inside double angle brackets. 00:37:59.480 |
The other is by putting it inside any kind of tag and then adding a special attribute 00:38:06.640 |
called ng-model and in that you can put something which is in dollar scope. 00:38:16.760 |
I actually want to show you the simplest way that this can possibly work, which is to go 00:38:26.800 |
into our list dot HTML and actually add an input tag, so something we can type into and 00:38:40.260 |
in this case, let's actually create this ng-model tag and we're going to call it test. 00:38:47.680 |
You can have a think about what this is going to do, you expect. 00:39:03.520 |
What's happened behind the scenes here is that as I typed into this text box, here's 00:39:12.720 |
one thing that I didn't show you how cool it is, is that this binding between dollar scope 00:39:21.480 |
So in this case, I changed something which had an ng-model defined. 00:39:29.160 |
Changing that thing caused dollar scope dot that thing to change because that's the very 00:39:34.440 |
definition of this tag and then there was something else bound to it which therefore 00:39:41.960 |
So what this means is that we can now write pretty sophisticated logic in our JavaScript 00:39:49.320 |
and have it automatically appear in our HTML. 00:39:52.280 |
So this binding between dollar scope and the application is where the magic happens. 00:39:57.920 |
How does it know to put testing into the input tag? 00:40:06.000 |
The reason is that app.js has been configured with the controller being called list controller. 00:40:13.280 |
In the list controller, it runs a line that goes dollar scope dot test equals testing. 00:40:18.400 |
So dollar scope dot test now equals testing and the ng-model here creates a two-way binding 00:40:26.080 |
between dollar scope dot test and this input so therefore since it's a two-way, it displays 00:40:32.800 |
the initial value of dollar scope dot test which then gets overwritten as soon as I type 00:40:43.680 |
So let's put this to work and actually do something useful, shall we? 00:40:53.640 |
Just seeing if I've got any useful tags for that. 00:41:02.640 |
So Bootstrap is the thing that's going to make things look half decent and in Bootstrap, 00:41:10.280 |
you just use normal HTML but you have to give things particular classes to basically say 00:41:16.480 |
So I generally have a bunch of templates for Bootstrap to stick in those classes for me. 00:41:20.800 |
So I'm just going to use the Bootstrap template to set that up for me. 00:41:27.640 |
So in our particular case, we're going to need text due date and priority. 00:41:34.400 |
So we'll have text - in fact, we probably don't want to call it or just say it to do due - let's 00:41:51.080 |
put that second, priority and then due - they're just the headers, okay? 00:42:00.880 |
Now we need this row to repeat enough times one for each todo item. 00:42:08.720 |
At this stage, we don't have any todo items, so we need to find some way of retrieving 00:42:13.800 |
So let's just see what this looks like at this point. 00:42:16.640 |
Okay, so at this point, all we've got is just some headers. 00:42:22.240 |
So we now need to write some JavaScript, which is actually going to go into our web application 00:42:31.040 |
server to that web API, that JSON API, and retrieve a list for us. 00:42:39.120 |
Angular already has something which can do all the standard CRUD operations for us, and 00:42:47.160 |
And to create one of these things, there's, again, basically a standard bit of boilerplate 00:42:50.960 |
that you have to type, which therefore means that I already have a template for it. 00:43:03.520 |
So as you can see, all I did was basically put the name of the application. 00:43:18.320 |
We can check that by checking our controller, yep, api/todo. 00:43:22.800 |
So this basically says any time we want to interact with our API, go to that path. 00:43:43.000 |
Now I want to have a list of my todos available to my HTML. 00:43:47.880 |
Or I'm going to have to put the list of those HTMLs inside Dollascope. 00:43:51.520 |
That's the definition of what Dollascope's all about, right? 00:43:53.840 |
So Dollascope.todos equals, OK, we've got to set it equal to the result of going to 00:44:02.520 |
I can use this resource I just created, which is called todo. 00:44:26.740 |
This is where I want to show you the Angular documentation. 00:44:30.680 |
It's really great, the Angular documentation. 00:44:41.280 |
It creates something with this particular API, and the thing to do a get is called query. 00:44:50.600 |
And so that's going to do exactly the same as just typing /api/todo. 00:45:11.080 |
So that should create a Dollascope.todos which should contain all of our todos which has 00:45:17.000 |
been sucked in from the web server over that API. 00:45:19.840 |
The only other thing I need to do then is loop through each of those and stick them 00:45:26.080 |
And it so happens that Angular already has, not surprisingly, a way to loop through something 00:45:33.840 |
and stick it into HTML, and it is called ng-repeat. 00:45:42.680 |
And what this does is everything inside that ng-repeat is going to get repeated for each 00:45:50.080 |
So we can now simply use that angle bracket notation like this. 00:45:59.400 |
So we've got todo, then priority, then due date. 00:46:30.760 |
I'm actually really glad this error happened because this is tricky and it's really neat. 00:46:59.760 |
This list here of parameters that's being sent into our controller, it's really quite amazing. 00:47:07.560 |
You can actually put any parameters you like here in any order as long as they have the 00:47:15.060 |
right names, and Angular will automatically send them to your controller for you. 00:47:24.120 |
Behind the scenes it's using something called dependency injection which some of you may 00:47:29.400 |
In our case we want to make sure that this todo object is available in this controller, 00:47:38.440 |
And just the fact that it has the same name as the thing we created up here means that 00:47:42.480 |
Angular is going to automatically create it for us and pass it to our controller. 00:47:46.600 |
So that's just something you basically have to know. 00:47:57.040 |
I don't think you need to be on top of dependency injection in detail. 00:48:00.280 |
All you really need to know is that, and it's something maybe in a later tutorial I go into 00:48:04.520 |
more detail, there's basically a concept of like in a lot of languages you have something 00:48:09.520 |
called global variables which allow you to access a particular variable everywhere in 00:48:15.640 |
They're considered bad software engineering practice because you can end up with multiple 00:48:22.400 |
This is a way of having something that's like global variables but you specifically say 00:48:28.000 |
So in this case I said any time that somebody says that they want something called todo 00:48:32.960 |
this is how you're going to construct it and then this is how I say I want something called 00:48:38.200 |
That's basically what dependency injection does. 00:48:42.560 |
Most importantly though we now have a working list here. 00:48:52.220 |
The only other thing I want to do in the last three minutes is make this look a little bit 00:48:56.320 |
better because currently that's a rather ugly way to display a date. 00:49:01.640 |
One of the handy things inside Angular is something called filters. 00:49:10.760 |
And filters are basically ways that we can change the way that something is displayed. 00:49:15.040 |
There is a date filter which is going to take a date and display it in a particular way. 00:49:19.360 |
The way that you use a filter in your HTML is by simply, you think of it as piping it 00:49:29.600 |
So we're going to use a filter called date and in particular date takes an argument and 00:49:51.040 |
So that's basically the end of this part I think because this has really contained a 00:50:00.360 |
We've gone from end to end, well from end to middle perhaps which is starting from nothing. 00:50:11.680 |
We've created a template and that took us an hour although I think if I wasn't explaining 00:50:18.960 |
things hopefully we could have done the whole thing end to end in one hour.