back to index

AngularJS 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

Whisper Transcript | Transcript Only Page

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:11.840 | Framework code first.
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:50.640 | pretty powerful web applications.
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:06.440 | started with it.
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:25.040 | not look too sucky.
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:39.160 | it look pretty good.
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:02:59.960 | on your own laptop.
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:12.800 | is that we're going to be building.
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:30.240 | In fact we might as well just type that.
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:04.080 | need to delete.
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:13.840 | of an existing one.
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:53.240 | language which is JavaScript.
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:00.800 | running that through CSS styles.
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:29.400 | using something called REST.
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:47.000 | called GET.
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:04.160 | would get turned into an update statement.
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:20.920 | do competition and so forth.
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:45.720 | them.
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:20.240 | are its properties.
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:39.120 | to do.
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:37.560 | Would it be nice to have a due date?
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:46.200 | at a point where we have a working API.
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:44.880 | the scenes, let's have a look in SQL Server.
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:13.800 | created a table for us.
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:46.360 | So why JSON over XML?
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:15.760 | and everything supports it.
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:26.800 | forth.
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:38.040 | super easy.
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:42.640 | going to simply show it to you.
00:18:44.400 | In Python, I've used here something called Flask Restless, which is kind of like a web
00:18:49.840 | API equivalent for Python.
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:08.240 | So that whole section is really easy.
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:22.600 | see why.
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:52.720 | called seeding the database.
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:28.000 | the database, so on and so forth.
00:21:30.560 | So we run a command to turn it on.
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:54.080 | data.
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:06.200 | Some of these are slightly different names.
00:22:18.000 | There we go.
00:22:31.080 | So you can see what's happening here.
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:46.280 | will just be the number to do.
00:22:48.800 | So this will just give us some data which makes life a little bit easier to start playing
00:22:52.440 | with things.
00:22:55.160 | And so the other reason I wanted to show you this is basically to show you how easy it
00:22:59.960 | is to work with the database.
00:23:01.380 | So although the database got created automatically, it's very easy for us to edit the database
00:23:06.840 | later.
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:19.360 | in the database.
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:51.160 | quite neat.
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:02.920 | most well-known version of it.
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:16.800 | Okay, so here's our seeded database.
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:25:55.160 | there isn't for this one.
00:25:57.960 | So now we're going to do Bootstrap.
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:16.760 | them.
00:27:17.760 | So let's create an index.html.
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:39.200 | out of my webpage.
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:28:59.680 | modify this now.
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:20.160 | and explain why that code is what it is.
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:41.960 | So let's create that now, 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:16.320 | you go to the root.
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:07.000 | to be a bit conceptual.
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:33.680 | it, that's what your browser does.
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:48.080 | the JavaScript that we wrote.
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:11.360 | All Angular specific stuff starts with ng.
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:42.380 | JavaScript for that application.
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:51.040 | that application.
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:23.600 | So there are the three pieces here.
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:07.560 | much this way.
00:34:11.320 | So let's go back to writing some code.
00:34:15.680 | In this case we need to create our controller and we're going to create something which
00:34:20.640 | is as basic as possible.
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:41.000 | So let's do that.
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:34.200 | together.
00:35:35.200 | So let's save all that and see what happens when we go to that page.
00:35:46.880 | Okay, so that's interesting, right?
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:18.440 | HTML from the template and display it.
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:33.960 | is dollar scope.
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:55.960 | is called dollar scope.
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:31.480 | brackets.
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:38.760 | of this.
00:37:39.760 | It's something that comes out of dollar scope.
00:37:42.760 | How neat is it?
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:38:57.000 | Isn't that amazing?
00:39:01.960 | That's really cool, right?
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:18.000 | and the template is actually two-way.
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:39.720 | changed at the other end.
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:39.760 | into it.
00:40:41.760 | Exactly.
00:40:43.680 | So let's put this to work and actually do something useful, shall we?
00:40:48.040 | So in our case, this is meant to be a list.
00:40:50.200 | So lists deserve to go in tables.
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:14.420 | make this look the Bootstrap way.
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:41:58.680 | And now we need the actual data.
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:12.480 | them.
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:45.280 | it's called $resource.
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:01.960 | And it's that.
00:43:03.520 | So as you can see, all I did was basically put the name of the application.
00:43:09.240 | In this case, the path is api/todo.
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:40.840 | And let me show you how easy this is.
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:43:58.920 | my server and pulling down a list of todos.
00:44:02.520 | I can use this resource I just created, which is called todo.
00:44:15.440 | And it has a query method.
00:44:25.280 | How do I know it has a query method?
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:34.280 | What does $resource do for us?
00:44:41.280 | It creates something with this particular API, and the thing to do a get is called query.
00:44:48.480 | So that's what I'm going to call this 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:22.560 | into my JavaScript.
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:46.440 | item in todos.
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:05.780 | Let's check it out, shall we?
00:46:11.920 | Todo is not defined.
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:26.900 | have come across in software engineering.
00:47:29.400 | In our case we want to make sure that this todo object is available in this controller,
00:47:35.500 | which means we actually have to pass it in.
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:14.640 | your program.
00:48:15.640 | They're considered bad software engineering practice because you can end up with multiple
00:48:19.560 | libraries defining the same global variable.
00:48:22.400 | This is a way of having something that's like global variables but you specifically say
00:48:27.000 | where you want them.
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:37.200 | todo.
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:28.000 | to 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:34.920 | I want to use medium date.
00:49:41.640 | There we go.
00:49:51.040 | So that's basically the end of this part I think because this has really contained a
00:49:58.240 | lot of the concepts that we've needed.
00:50:00.360 | We've gone from end to end, well from end to middle perhaps which is starting from nothing.
00:50:06.160 | We've created a database.
00:50:07.560 | We've created a REST API.
00:50:10.520 | We've created a controller.
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.
00:50:22.800 | That's the theory anyway.
00:50:23.880 | [BLANK_AUDIO]