Tuesday, April 25, 2017

Angular 2 - External Libraries

This is the fifth in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  Previous installments in the series can be found here, here, here, and here.  I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first four installments you can get the code that was generated during the fourth installment by visiting Github (here) and switching to the routing-part-deux branch.

In this installment we're going to learn how to use external libraries, and some pitfalls to watch out for when you do it.  We've got a lot of functionality, but our website looks... well, bad.  Let's use Bootstrap to make it look better.  I'll go ahead and tell you right now that I'm not a design expert so even when we're completely finished here our site might not look very "good", but it will look better than it does right now.

The first thing we need to do is get bootstrap.  As of this writing Bootstrap 4 is in alpha, but I like what they're doing with it so that's actually what I'm going to use.  It doesn't matter, though.  The point of this post is to show you how to use any third party library, not specifically Bootstrap.  Assuming the library you want to use has an npm package you'd go ahead and install the package at the root level of your module (D:\Dev\Learning\Angular2\Cli\ProveIt).  I'm running npm install bootstrap@4.0.0-alpha.6 --save, which will install that specific version of Bootstrap and save it as a dependency.  This also installs Boostrap's dependencies (jQuery and tether) so we're all good to start using it now.

Now that we've got it installed we need to include the appropriate references in our project.  In a pure JavaScript application we'd just add a <script> tag to our index.html and we'd be all set, but that's not how we do things with the Angular CLI.  We need to add a reference to the bootstrap css that's now in our node_modules folder.  Open your .angular-cli.json file and add the relative path reference to bootstrap's css (or sass or scss) file to the styles array.  The styles array should be around line 21 and should currently contain a single value: styles.scss (remember we modified this array in the first installment of this series, too).  My relative reference is "../node_modules/bootstrap/scss/bootstrap.scss".  As soon as you've added that, serve the application and you should immediately see that your links are styled slightly differently.

That's all well and fine if the external library has an npm package, but what if it doesn't?  That's easy enough, too.  For the sake of demonstration let's say you want to use a custom build of Bootstrap, which is a common enough scenario.  So you go to getbootstrap.com and build your customized version, which includes CSS and JavaScript files you need to include.  You unzip them and save the minified files... where?  I like to create a vendor directory in my Angular CLI project directory so I'd save my files in D:\Dev\Learning\Angular2\cli\ProveIt\src\vendor\bootstrap.  Once the files are in a directory I can reference I need to add them to my .angular-cli.json file the same as I did before.  This time I also have a .js file I want to reference so I also need to modify the scripts array, which is just after the styles array in the same .json file.  My references are "./vendor/bootstrap/bootstrap.min.css" and "./vendor/bootstrap/bootstrap.min.js".  I removed my other bootstrap reference just to be sure everything is working as desired and when I serve my app again it looks good.

As far as I can tell, the CLI will respect import order so if you have conflicting styles in some stylesheets, the last styles imported will be used.

Right now I'm getting an error in my console that says that "Bootstrap's JavaScript requires jQuery at eval", which tells me I forgot to include jQuery in my scripts array.  I'll just add the reference to it from my node_modules folder and I'll be all set.

I'm going to do a little bit of styling, but I'm not going to describe it here.  I'm basically just going to move things towards the center of the page, use a jumbotron and list item styling to make my students page look better.  You can do your own or view my completed code on Github (the link is below).

There's another way to reference external libraries for consumption within an Angular project, but I'm not going to cover that quite yet.  It will probably be the topic of the next installment of this guide.  For now, the final code from this module can be found on Github (here).  Switch to the external-libraries branch.

Wednesday, April 19, 2017

Angular 2 - Routing Part Deux

This is the fourth in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  Previous installments in the series can be found here, here, and here.  I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first three installments you can get the code that was generated during the third installment by visiting Github (here) and switching to the routing branch.

In this installment we're going to continue learning about routing and finish up the routing we started in the last installment.  Right now we have an application that has routes configured to view all students and one individual student (by id) as well as a redirect route from our root URL and a route for when the page is not found.  That's great and everything, but we're missing a couple of key pieces.  First, our individual student page just doesn't work.  If we navigate to /student/1 (or any number for that matter) we get a blank page and if we check our console we see a bunch of errors, so what gives?  Well, our individual student component (StudentComponent) isn't designed to work with our individual student route (/student/1).  Our StudentComponent has an input property of student, but when we navigate directly to the StudentComponent via the router, there is nothing input so our template parsing fails.  We can fix it pretty easily, though, so let's do it.

First we'll create a service in the common folder.  The command for a service is ng g service studnet. Make sure to run this command from inside the common folder (D:\Dev\Learning\Angular2\cli\ProveIt\src\app\common) so that your service files get created in the right location. Unlike when it creates a component, when the CLI generates a service it does not generate a new folder for the service. Since we want it in common we need to be in common when we run the command. We want to move the students array out of the StudentsComponent and into this service so the array can be shared between components more easily. You can just copy/paste the entire students array directly from students.component.ts to student.service.ts. Once we've done that we need to import the service in the StudentsComponent, inject the service into the component through the constructor, and initialize the students array of the component so it can be displayed to the user. Here's what my students.component.ts file looks like after I do all of that:
import { Component, OnInit } from '@angular/core'; import { Student } from '../common/student'; import { StudentService } from '../common/student.service'; @Component({   selector: 'app-students',   templateUrl: './students.component.html',   styleUrls: ['./students.component.css'] }) export class StudentsComponent implements OnInit {   selectedStudent: Student;   students: Student[];   constructor(private studentService: StudentService) { }   ngOnInit() {     this.students = this.studentService.students;   }   show(student) {     this.selectedStudent = student;   } }

I want to take a quick moment to discuss the constructor up there. What you see in there is actually a shortcut to create a private variable called studentService that is of type StudentService, and also assign the StudentService provider to the studentService variable. That constructor code allows us to assign the students property that's in the StudentService to the students variable in the StudentsComponent, which we do in the ngOnInit function. The next change we need to make is actually at the module level. We need to add the new StudentService as a provider to the entire module. To do that, import StudentService in app.module.ts, then add StudentService to the providers array (it will be the only item in the array after you add it).

Now that we have our students all stored in a service we can add the piece that we need to fix the StudentComponent.  In student.component.ts we have an ngOnInit method and that's where we want to get the student whose id matches the id passed in the URL.  The first thing we need to do to facilitate that lookup is import the StudentService in this component and inject it in the constructor.  That code is identical to what we did in the StudentsComponent so I won't repeat it here.

Next we want to change the ngOnInit function to get a single student.  Since we're doing this in small steps, let's just get the first student from the students array and use it.  To do that we'll be setting this.student to the first element of the students array on the StudentService, like this:this.student = this.studentService.students[0];

Now if you navigate to /student/1 you should see the details of the student with id 1.  Huzzah!  But that's not really what we want because if you navigate to /student/2 you'll still see the details of the student with id 1.  So we need to wire up our URL to our lookup the correct student based on which id was passed.  To do that we actually need to bring a couple more pieces into our StudentComponent: ActivatedRoute and Params from @angular/router, and we want to import switchMap, Observable, and observable.of from rxjs.  Here are the imports you'll want:
import { Observable } from 'rxjs/Observable'; import { ActivatedRoute, Params } from '@angular/router'; import 'rxjs/add/operator/switchMap'; import 'rxjs/add/observable/of';

Next, we need to modify the constructor to inject the ActivatedRoute and set it to a private variable called activatedRoute (again, you can call it whatever you want, but in my code that's the name I used).

Now we want to use them in our ngOnInit function:
this.activatedRoute.params.switchMap((params: Params) => {   const internalStudent = this.studentService.students.find((student) => {     return student.id === +params['id'];   });   return Observable.of(internalStudent); }).subscribe(student => this.student = student);
Now if you navigate to /student/2 you see the details for the student with id 2.  Huzzah!  So what's that code actually doing?  I'm glad you asked!

The activated route provides information on the current route (the current "page") and the .params property of the activated route provides us the parameters that came in from the route.  switchMap is an rxjs function that cancels previous calls to the same route with different parameters.  That way if we go to /student/1, but then - before the route is finished - we change it to /student/2, the first call is cancelled and any calls to a remote API are cancelled as well.  This prevents the problem of getting the result of the first call back from a long running process after you get the results of the second call (since those calls would be asynchronous).  Inside switchMap we have a callback function that looks up a student based on their id.  The + in on the params['id'] check converts the parameter value to a number so the lookup is successful.  We're using Observable.of (another rxjs capability) to return an observable as the result of the switchMap function so we can subscribe to the observable.  Observables and subscriptions are an advanced topic (that I don't fully understand yet) that I'll cover in a future installment of this guide.  For now, just accept it.  Our .subscribe function assigns the result of the switchMap (I think) to the student property of the component.

The very last thing we need to do is change our StudentsComponent to take the user to the student detail page when the user clicks on one of the students.  Right now when they click we show the details on the bottom of the page so we want to remove that and replace the click function of our div to an anchor tag that is a routerLink.  Here's the updated markup from students.component.html:

<div *ngFor="let student of students">   <a [routerLink]="['/student/' + student.id]">{{student.id}} {{student.name}} {{student.teacherId}} {{student.age}}</a> </div>


This is pretty straightforward once you know about the [routerLink] directive.  We're still iterating through all of the students and displaying their info, but now we're doing it inside an anchor tag that applies the [routerLink] directive.  We're appending the current student's ID to the /student/ route and voila!  We have a working app.  Of course there are still quite a few mysterious parts that we'll need to clear up, but we'll get there.

The final code from this module can be found on Github (here).  Switch to the routing-part-deux branch.

Tuesday, April 18, 2017

Angular 2 - Routing

This is the third in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  The first installment in the series can be found here, and the second can be found here.   I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first two installments you can get the code that was generated during those parts of the guide by visiting Github (here) and switching to the second-installment branch.

In this installment we're going to learn about routing.  Routing is the method we use to show different content depending on the URL the user has visited.  Routing enables us to load the majority of our resources and content once time and then inject different content whenever the user changes the route (by clicking a link, a button, changing the URL in the address bar, or some other method).  If you're still a little bit confused try to imagine a childrens toy called the View Master.  It's a set of lenses that the child can look through to see a picture.  When they click a button the picture changes.
The child doesn't have to change the entire View Master to look at a different picture, he just flicks the tab and a new picture appears for him.  Routing works the same way.  The overall structure of the page and the resources stay right where they are (this is the View Master part) and the content that is injected changes when the user clicks a button (this is the picture wheel the View Master uses).

Routing has been around for a while and Angular JS (aka Angular 1.x) had sort of a love/hate relationship with routing.  I know that I tended not to use the built-in routing in Angular 2, favoring the more robust (at the time, at least) ng-router.  In Angular 2, though, the team decided to make things easier and incorporate them a bit more.  Since the whole framework is more modular anyway it worked out quite nicely to have routing in a separate module that can be used... or not.  On a side note, the reason the team jumped over Angular 3 and went straight from 2 to 4 was they wanted to keep the version number of Angular in sync with the version number of the router.  Not pertinent in any way, but it seems like something useful to know.

Since adding routing is so easy let's just get started.  Create a new file as a sibling of app.module.ts (so mine will be created at D:\Dev\Learning\Angular2\cli\ProveIt\src\app) named routes.ts (the name doesn't matter so if you don't like routes.ts name it whatever you want).

The first thing we need to do in our new file is import Routes from @angular/router:import { Routes } from '@angular/router';

Now we need to import the components we'll use in our routes.  When someone visits http://www.mysite.com/students we want them to see our StudentsComponent, but if they visit http://www.mysite.com/student/1 we want them to see our StudentComponent for the student with id 1.  To do this we'll need to import both components in our routes.ts file.  You should know how to do that by now so I'm not going to show you.

Let's set up the routes to do what we just described.  Create and export a constant named appRoutes that is of type Routes:
export const appRoutesRoutes = [];

Now that we have our constant defined it's just a matter of adding the routes that we want.  Each route object can have a path and a component property. Create the routes (inside the appRoutes array):
path: 'students'component: StudentsComponent }, { path: 'student/:id'component: StudentComponent },

Now that we have our route constant created we need to wire it up to our module so go to your app.module.ts file and import the appRoutes constant from the routes file:import { appRoutes } from './routes'. Now we need to import RouterModule from @angular/router and use it to bring in our appRoutes constant. I'll leave the import statement to you, but here's how you'd use it (in the imports array in your @NgModule recipe):RouterModule.forRoot(appRoutes),

The last thing we need to do is change our app.component.html to use the router instead of loading our StudentsComponent directly.  We do that by modifying the html to be: <router-outlet></router-outlet>. If you're running your app you'll probably notice that now all you see is a blank screen. That's because the app is navigating to the root ("/") and we haven't configured that route. Change the URL to have /students on the end and you should see your students component.

We can actually configure the root route to redirect to our students route pretty easily so we'll go ahead and do that now.  Back in routes.ts add one more route to the list, but this one won't have a component property, it'll have a redirectTo property.  Like this:path: ''redirectTo: 'students'pathMatch: 'full' }.  With just this last change we can navigate to our root URL and be redirect to our students list (it even updates the URL in the address bar for us!).

OK, that wasn't the last thing.  We have one more optional item.  We can add a PageNotFoundComponent and redirect all other routes to go there instead of throwing an error.  The only piece of information I haven't given you to do that on your own is that the path of the route you'd want to create is **.  My final version is checked in on Github, on the routing branch.  We have a bit more to cover with routing, but this post is getting long so I'm going to end here and pick up the rest in another installment.

Friday, April 14, 2017

Angular 2 - Our First Component

This is the second in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  The first installment in the series can be found here.  I'm going to build on what I did in that post so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip that first installment you can get the code that we generated during that part of the guide by visiting Github (here) and switching to the first-installment branch.

At this point we have our basic application running and we essentially have "Hello, World" going in our browser.  That's a great start, but it doesn't really do anything for us.  Let's build out the application by displaying a list of students in the UI.  We're not going to worry about styling right now.  Instead we're just going to show each student in a separate div.  We can style it later (or not, whatever).

Let's take an object-oriented approach to this part (I know, "object-oriented approach to JavaScript?!?!", but yes.  We're using TypeScript and the newer versions of the ECMAScript specification support designing objects).  What is a student?  For our purposes we're going to say a student has the following characteristics:

  • id
  • name
  • teacherId
  • age
If we were writing in C# we'd create a POCO that represents a single student and specify somewhere that we have a List<Student>.  Since this is TypeScript we're going to do things slightly differently.  Create a new folder under src/app and name it "common" (obviously without the quotes).  In your command prompt, navigate to that new folder (so I navigated to D:\Dev\Learning\Angular2\cli\ProveIt\src\app\common) and run the command ng g interface student. This creates a new interface called student in the common folder.  Go ahead and open that file (src/app/common/student.ts) and you'll see that it's pretty simple at this point.  It's just a declaration and export of what amounts to a POCO - or in this case a POJSO (Plain Old JavaScript Object).

We can add our properties to the interface and specify their type.  Our new interface looks like this:
export interface Student {     idnumber;     namestring;     teacherIdnumber;     agenumber; }
All we've done here is specify what a Student looks like to us.  Now we're going to use our Student interface in our StudentsComponent.  Open src/app/students/students.component.ts and import the new Student interface at the top of the file.
import { Student } from'../common/student';
Now that we have our Student interface available to us, we'll create a property on our StudentComponent that is an array of Students.  Just inside the creation of the StudentComponent class (so this would be above the constructor) add this line: studentsStudent[] = [];. This tells Angular that our every single object in our students array is going to implement the Student interface. Doing this gives us type checking while we develop. In Angular! How cool is that!?

Go ahead and populate the students array with 5 students.  Just make up the information.  I usually use pop culture characters and consecutive numbers for ids.

If you're not already serving your application you should do that now and make sure everything still works properly.  In your command prompt navigate to the application directory (so mine is D:\Dev\Learning\Angular2\cli\ProveIt) and run the ng serve --open command.  You should still see "students works!" as the only thing on the page.  We're about to change that.

Open your students.component.html file and replace the contents of the file with this:
<div *ngFor="let student of students">   {{student.id}} {{student.name}} {{student.teacherId}} {{student.age}} </div>
If you look at your application now you'll see each student's information listed on a separate line. Sweet! That's what we were going for. Remember that at least for now we don't really care how it looks. In a future installment of this guide we're going to bring in Bootstrap and style this up a little bit better. For now we have a little bit more work to do.

Let's create another component; one that allows us to view the details of a student.  Right now we only have a little bit of information about them, but we want to be able to see more.  To create a new component we'll use Angular CLI from the command prompt.  Go to src/app and run the command ng g component student to create a new StudentComponent.  If you're worried that the name will be too easy to confuse with the current StudentsComponent you can name it something else (like student-detail) if you want.

Open the newly created student.component.ts and we're going to jump right in to making some changes.  Right away we want to import Input from @angular/core so you can just add it after the import of OnInit (in the same curly brace).  We also want to import the Student interface like we did in the StudentsComponent.  In fact, you can copy that line exactly from StudentsComponent into StudentComponent.  Next we'll add an input property called student.  Add this line just above the constructor: @Input() studentStudent;  Setting the @Input() decorator on this property tells Angular that we're going to get this value as an input wherever the StudentComponent is used.  Add city (as a string) to the Student interface, then update the list of students so that each student has a city.

In student.component.ts replace the templateUrl with an inline template by replacing the entire templateUrl line with this: template'<p>{{student.name}} lives in {{student.city}}</p> So now all we need to do is figure out which student's information to show and how to show it.  We're going to go back to students.component.html and make a few changes now.  Oh, you can delete student.component.html if you want to since we're not using it anymore.

Back in students.component.html we're going to add a click handler on the main div that's repeating for each student.  When the user clicks on a student in the list of students we're going to invoke a function called show and pass the current student to that function: (click)="show(student)" You'll want to add that to the <div> that has the *ngFor on it. Down below that <div> we're going to introduce the student component by adding this code:
<app-student *ngIf="selectedStudent" [student]="selectedStudent"></app-student>
Now we'll wire up that click event to set the selectedStudent to whatever student was passed to the function. First we need to add a property called selectedStudent that is of type Student. You should know how to do this by now so I'm not going to show you.
show(student) { this.selectedStudent = student; }
So now we have (sort of) a working app. We can see a list of students and we can click on a student to view his "details" (such as they are). We have two components working together and we have an interface keeping us honest with our Student objects. We've taken an object-oriented approach to creating an Angular 2 application and so far it's going pretty well. We'll look at routing in our application in the next installment, btu that's all for now.

Angular 2 - Getting Started with Angular CLI

Angular 2 (finally) went live in September 2016 and I (finally) have had a chance to work on it, both at work and on a couple of personal projects.  This post is a bit of a deviation from the overall intention of my blog in that there are already some pretty good guides available for getting started with Angular 2.  The only reason I'm writing this one is to make sure I understand the ins and outs of doing it myself.  So, I guess in that regard, this post isn't a deviation at all.  Huh.  Cool.

I'll start off by pointing out that, yes, Angular 4 is already released (don't worry they just skipped 3).  I plan to work with 4 soon enough, but so far what I've done has been in 2 so that's what I'm documenting.  Since 4 is already out it can be a bit tricky to find the documentation for 2, so here's a link to it: https://v2.angular.io/docs/ts/latest/.  Now that that's out of the way, let's dig right in.

OK, so you'll still need npm (and therefore node.js) installed so if you haven't done that yet, do it now.  With npm installed you can install the Angular CLI globally with the following command: npm install @angular/cli -g.  All of the CLI documentation can be found here.

I've checked in the code that corresponds to this series on Github.  You can find it here.  For this installment of this guide you'll want to checkout the first-installment branch.

Once the CLI is installed you just have to run the following command in the directory you want to create your project: ng new [project name] where [project name] is the name of your project. So I'm going to create a project at D:\Dev\Learning\Angular2\cli called ProveIt. I'll navigate to D:\Dev\Learning\Angular2\cli in my command prompt and run ng new ProveIt. Creating the project using the CLI is the easiest way I've found.  You should be aware that the CLI uses Webpack so if you come across some bit of help (that's probably outdated) that talks about SystemJS, that probably won't work for you if you're following this guide.  ng new initializes git and installs a ton of npm packages for you so it takes a few minutes to complete.  Once it does finish, though, you actually have a working, testable application.  To prove it you can navigate into the directory you created (for me, that's D:\Dev\Learning\Angular2\cli\ProveIt) and run the command ng serve --open.  That will build your Angular 2 project, host it on port 4200, and launch your default browser to the root level of the application.  You should see a message that says (as of this writing) "app works!".  Congratulations!  You've "written" an Angular 2 app!

So now we have the default app running, which is a great start, but it isn't really an application.  At least, it doesn't do anything.  Let's use the CLI to add a new component to the application, called students.  Open a new command prompt and navigate to your new project (D:\Dev\Learning\Angular2\cli\ProveIt).  From there you want to go forward to src/app and run the command ng g component students.  This command is much faster, and creates four new files and modifies one file.  It's time to open our application.  I prefer VS Code, but you can use whatever you want.  Open the ProveIt folder and we'll explore some of the files that have been created so far.

.angular-cli.json

This is the configuration file used by the CLI to bootstrap the application when you run ng serve.  The CLI includes a built-in SASS parser so one of the first things I always do is change my styles.css to styles.scss and update this file to reference the .scss file instead of the .css file (line 22 as of this writing, but it's in the "styles" array).  If you want to include any 3rd party scripts (like Bootstrap) you'd add their relative path (assuming you added them via npm they'd be in node_modules/...) to the "scripts" array.  Finally, if you have nested directories with assets you want to deploy (like images or customized fonts) you'd add those to the "assets" array.  Just adding the top-level folder should be enough to include the entire directory in the output.

index.html

This file is the only file initially loaded by the application. Since Angular is focused on creating Single Page Applications (SPAs) this is that single page. From here on out everything that gets loaded just enhances the DOM or functionality of this one page. If you look in the <body> tag you'll see that we start off with an unknown (at least to HTML) tag called <app-root>. As we'll see in a few paragraphs this is actually an Angular component. Just keep this in mind as we move forward.

src/main.ts

This is essentially the entry point for the compilation of your application. I'm not going to lie and tell you I know exactly how this works, because I'm still a little murky on it, but I can tell you that it's where your browser gets told which module to start with. It should be defaulted to AppModule.

src/app/app.module.ts

This is the declaration of the AppModule.  You can see at the end of this file that AppModule is exported, which allows it to be used by main.ts as the bootstrap module.  You can also see that this file imports the necessary modules from various @angular folders that you're going to need to run this application in the browser.  Finally, there are two components imported and listed in the declarations section.  Part of using the Angular CLI to generate a new component (like we did earlier) is that the CLI will edit this module to import and declare your new component automatically so you don't have to worry about that part.

src/app/app.component.ts

This is where the actual AppComponent is declared and exported so it can be used in the AppModule as the bootstrap component (which means it's where the whole application starts).  You can see that the Component recipe is imported from @angular/core and then the class (AppComponent) is decorated with the @Component decorator, which specifies the selector for the component, the location of the template for the component, and the location of the stylesheet for the component.  This component has a single property, called title.

src/app/app.component.html

This is the markup that will be injected wherever Angular 2 finds our app component being used.  In other words, when we use <app-root></app-root>, Angular 2 will inject whatever is in this template file inside those tags.  Right now it's just a placeholder that displays the title inside of an <h1>, which is why we see "app works!" when we run the application.  The value of title is being set in app.component.ts and then displayed here.

If we examine the students.component.ts and students.component.html files that were created by the Angular CLI we'll see that they are very similar to the app.component.* files we just looked at.  Components are the basic force within Angular 2.  Components allow us to manipulate the DOM to do and show what we want.  One thing we haven't done yet is use our StudentsComponent in our application.  Let's go back to index.html and take another look.  Knowing what we know now about our AppComponent and its selector we can see that Angular is being told to inject the contents of src/app/app.component.html between the opening and closing <app-root> tags.  We want to do basically the same thing with our StudentsComponent so let's make that happen.  Open src/app/app.component.html and replace {{title}} with <app-students></app-students>.  If you left Angular CLI serving the application then just look at that tab in your browser again and you should see that the message has changed to "students works!".  What's happening is that Angular finds the <app-root> tag and injects the contents of the AppComponent in there.  While Angular is injecting that content it comes across the <app-students> component and realizes it needs to inject the contents of students.component.html into the AppComponent markup.  Since the content of our StudentsComponent is a simple message that says "students works!" (as you can see by opening src/app/students/students.component.html) that's what we see in our browser.

I'm going to end this post here because I think there's been a lot to digest so far.  This will only be the first in a series that I'll hopefully get up pretty quickly.  I'm still learning Angular 2 so don't take what I say as absolute truth.  Remember that I'm just putting up my thoughts to help me out in the future.