Applies To
Angular CLI: 7.3.9
Node: 10.1.0
OS: Windows 10 x64
Objectives
- What is needed to get started developing with Angular.
- Why we need Node.js.
- Why we use NPM.
- Why we use the Angular CLI.
- Why VS Code instead of Visual Studio.
- How to create our first project.
- Understanding the basic structure of our project.
- Understanding navigation.
- How to build the project for deployment.
Heads Up!
Given the target audience of this article, an ASP.NET MVC Developer who wants to get a grasp on Angular, I am going to attempt to draw some comparisons between MVC and Angular that are loose at best. This is my effort to help bridge a gap of understanding. Clearly, these two technologies are very different, but both follow the Model View Controller pattern. Because of this, my comparisons between ASP.NET MVC and Angular are meant only as a guide, and not true representations of each other.
Introduction
I am ashamed to admit it, but I got really comfortable where I was. I had lived in the world of ASP.NET since .NET was birthed back in 2002. For many years I did everything Web Forms, but eventually transitioned into MVC. The design pattern between Web Forms and MVC was dramatic, to say the least, and it took me a bit before MVC felt natural.
So here I have been for many years, sitting in my comfort zone, writing and maintaining ASP.NET MVC web applications, with jQuery as my default client-side JavaScript framework, and Visual Studio, my IDE of choice.
I was introduced to Angular through a job change into a very forward-thinking and cutting edge driven organization that had made the decision to slowly move away from MVC, and transition into Single Page Applications (SPA) with Angular.
I suspect you may be here because like me, you found yourself facing a transition away from ASP.NET MVC to Angular. Being so ingrained in the ways of ASP.NET MVC, you may be feeling a bit overwhelmed at just how different things are in the world of Angular. The goal of this article is to try to help get you started on that transaction.
Tools Needed for the Job
I noticed many "Getting Started with Angular" articles either assumed the reader had some knowledge about Angular’s prerequisites, or that the reader likely didn’t care and/or need to know about the details as long as the reader was told what to install. Many articles are quick “do this, then that” type articles, which have their place, but for someone like myself who was jumping into completely new territory, I was looking for something more in depth that could give me more background on things.
So lets break things down into some detail! We will need the following in order to start developing Angular apps:
Node.js
An open-source, cross-platform JavaScript run-time environment which can be used for server side, client side, desktop & mobile applications. Node.js is comparable to the .NET run-time environment which executes C#, VB.NET and other supported languages. Node.js is the first thing we will need to install. This is used to serve our application and includes NPM.
NPM
Stands for “Node Package Manager”. It is a package manager for JavaScript built into Node.js. We will have NPM after we install Node.js. NPM is comparable to what NuGet is for .NET. NPM is needed to install the Angular CLI as well as various packages that will be used in the Angular app. NPM commands are prefixed with the term “npm”.
Angular CLI
Stands for “Angular Command Line Interface”. It simplifies creating angular apps by automating operations with quick commands so we don’t need to manually install and configure dependencies. Angular CLI commands are prefixed with the term “ng” (ng stands for a*ng*ular). For more information on Angular CLI click here. For a deep X 5 dive into the Angular compiler, see the following blog.
I highly recommend the following items to enhance our experience:
Visual Studio Code
Is optional, but the preferred editor. You can download it here. You may be asking yourself: Why use Visual Studio Code when we have Visual Studio?
One thing I noticed when attending my first Angular conference, NG-Conf 2019, was that among everyone I saw writing/reading code on their laptops, they were all using VS Code, both attendees, and presenters. I cannot say I saw a single instance of Visual Studio running on any machine there. I’m not a big fan of simply defaulting to something because “everyone else is doing it,” so here is my best guess.
Visual Studio | Visual Studio Code (VS Code) | |
---|---|---|
Cross Platform | No | Yes |
Open Source | No | Yes |
Cost | FREE (Community Edition) | FREE |
Size | 1 GB (bare minimum) | 210 MB |
Memory Consumption | Generally Higher | Generally Lower |
VS Code may not have all the bells and whistles that Visual Studio has, however, being cross-platform and open source means that learning and teaching Angular development is going to be much easier when we have a common IDE that is available to all.
For us veteran Visual Studio users, there are tutorials out there for creating Angular apps in Visual Studio, however, it probably isn’t a bad idea to just start getting used to using VS Code.
Angular Essentials
This is an extension for Visual Studio Code put together by John Papa, which is essentially a collection some of the most popular extensions.
Once we have everything above ready to go, in order to execute NPM / Angular CLI commands we can (1) Open command prompt, PowerShell, Git Bash, or something similar, or (2) use the Terminal window in VS Code (which basically opens up the previous option within the VS Code environment)
Setting Things Up
- Install
Node.js
. The installation can be downloaded here -
NPM
is built in to Node.js, so we are good to go here. - Install the
Angular CLI
. Open up a command prompt and execute the following:
npm install -g @angular/cli
A Basic Look Under the Hood
When Node.js and the Angular CLI are installed, you might be curious about how they integrate with your favorite command line interface. Entering the following command will give us a semicolon delimited list of all of the global paths we have defined in our system:
echo %path%
The two applicable paths that were setup during installation of Node.js are the following:
c:\Program Files\nodejs\npm.cmd
:: Created by npm, please don't edit manually.
@ECHO OFF
SETLOCAL
SET "NODE_EXE=%~dp0\node.exe"
IF NOT EXIST "%NODE_EXE%" (
SET "NODE_EXE=node"
)
SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js"
FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js"
)
IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" (
SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%"
)
"%NODE_EXE%" "%NPM_CLI_JS%" %*
C:\Users\[My Username]\AppData\Roaming\npm\npm.cmd
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\@angular\cli\bin\ng" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\@angular\cli\bin\ng" %*
)
We will also need the following file after we install the Angular CLI:
C:\Users\[My Username]\AppData\Roaming\npm\ng.cmd
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\npm\bin\npm-cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\npm\bin\npm-cli.js" %*
These are the paths that allow the command prompt, PowerShell, Git Bash, etc. to know where they can find the npm
and ng
commands (which ultimately point to
node.exe) no matter what directory we currently reside in, while putting our current directory in scope for the commands’ execution.
Get Comfortable with the Command Line
In my early days as a developer (way back in the late 1990’s early 2000’s,) GUIs were all the rage. Getting away from command line interfaces was the thing most users wanted, and most developers strived to produce. Visual Studio has done a great job over the years of providing a GUI for virtually everything, from project creation to interacting with Git repositories. Since becoming a developer, command-line tools seem to be more popular now due to open source. This makes sense, because an application needs to work within multiple platforms. Creating a GUI to support a wide range of commands and options can be time consuming with little real gain.
If you are anything like me, moving away from Visual Studio was definitely a move outside of my comfort zone. This was mostly due to shifting away from GUI's. GUI's provide menus, icons, and buttons to run commands. Whereas, you have to commit various commands to memory, or have a handy cheat sheet available, to use the command-line.
But alas! I quickly discovered that the move wasn't as bad as I thought it would be.
Creating Our First Project
Visual Studio users might expect to open up VS Code and find a File > New Project… menu item, and then complete a short wizard for setting up an Angular app, but this isn't how things are done in this general purpose lightweight IDE. In order to create a new Angular app, we need to use the Angular CLI. The Angular CLI will setup a basic project template with all of the basic files, configurations, and the structure needed to be able to immediatly run the application.
In the command prompt we will first want to change directory to the root folder where we want our Angular app set up. An example would be:
cd c:\Temp
Next, run the ng new command with the name of the app we want to create:
ng new my-app
We will be prompted to add Angular routing or not. For this project, please answer yes, since we will utilize this later.
We will then be prompted for which stylesheet format to use, I recommend selecting SCSS
.
This will then create a new folder within the directory we are currently in, as
well as all the files needed.
*If we get an “Unexpected end of JSON input while parsing near” error after executing an ng new command, something in our cache is likely corrupt. This was the case for me at one point, because I had previously installed things without understanding what I was doing, and things went stale. One way I was able to solve this was by executing the following command:
npm cache clean --force
Once this is completed, we need to change directory into our new application folder:
cd my-app
We can now run the application with the following command:
ng serve --open
This will start the server, and then open the application in the browser.
When executing ng serve
, the local server fires up and runs until you stop it, usually by typing [Ctrl][c]
in the terminal window. One really nice feature of this local server is that it utilizes a File System Watcher mechanism (possibly fs.watchFile built into node.js) that detects when there are changes to files within your directory structure. When a change is detected, such as when a file is saved, the server automatically re-compiles the application, and then refreshes it within the browser.
Understanding Our First Project
To begin editing the code, we do the following: Within VS Code, on
the menu, select File > Open Folder…
When I opened up my first Angular project folder in VS Code, I was overwhelmed and confused by all of the files created, as you might be. There will be very little that will look familiar to the old ASP.NET MVC developer. Despite there being a lot to digest here, there really are only a handful of files that we need to be worried about, at least for now.
The first thing we might notice, is that there are no core project and solution files that we are used to having associated with our .NET applications. When it comes to Angular development, everything simply resides within a directory structure. So rather than having Angular project files that keep track of the other files, references, etc. that belong to the project; files reside within the base directory and its subdirectories. This structure is our project. Therefore, when we open up a project in VS Code, instead of opening up a file, we open up a directory.
Let’s get acquainted with the following files:
package.json
This file contains the list of node dependencies, and it can be somewhat likened to a list of References in any ASP.NET project.
src/index.html
This file is basically a simple placeholder for our core Component. This is similar to the application-wide shared layout View in MVC (often named _layout). This is the core html that will be rendered for the application. Rather than adding additional html pages, you will use Angular Components with Angular Routing which will be discussed later.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
Everything in here should look pretty standard, that is, with the exception of the non-standard <app-root>
tag (line 12.) We will talk more about this next since it relates to Angular Components.
app/app.component.*
You will see several files in the app folder that starts with app.component. These files are all related to each other and make up an Angular Component. For comparison purposes, a component would look most like an MVC View or Partial View. Instead of creating additional HTML files on the root (in addition to Index.html) you will be creating more Components.
This particular component, however, is slightly different from other components you will create, because it is the root or parent component of the application and is generally associated with the Index.html. All other components that you create will exist in a parent/child hierarchy under this component. In a way, you could think of this component as the application’s core View or Layout, whereas all other components you add to the project would be like Partial Views.
The main component file is a TypeScript file called app.component.ts. This file is essentially the definition of the component where you set its various properties, wire up event handling, update the DOM, make calls to services, etc. This is like a Controller blended with a Model in MVC.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'my-app';
}
A key thing to note here is the @Component
decorator section (line 3-7). This defines various properties of the component. When a project is first created with a default component, these three properties are established.
Looking at line 4 you see the selector
property with a value of ‘app-root’
. If you remember back to the Index.html
file, there was that non-standard HTML tag <app-root>
. This means that the rendered content of this component is going to be placed where this <app-root>
tag resides in the Index.html
. Basically it is a placeholder for a component's content. Within MVC, this <app-root>
tag would be somewhat comparable to a @RendyBody()
in a Layout or placehold tags within components. It would be comparable to an @Html.Partial()
within a View.
Looking at line 5 you see the templateUrl
property. Its value points to the app.component.html
file. This file is where you can define the HTML that you want your component to render. Line 6 contains the styleUrls
property. It maps to the app.component.css
file which contains the CSS for this specific component.
src/app/app_module.ts
This is an important TypeScript file which is used to declare your components. If your components are not declared here, they will not be able to be consumed within your application.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
dist (Folder)
This is a folder that will not exist until you execute the ng build
command (I will discuss ng build
in detail later). This folder contains the output of the build and represents the content to be deployed to a web server.
So, to recap a bit on the descriptions above, the following image shows the contents of an Angular 7 application, loosely compared to an MVC application:
Get Comfortable with Angular CLI Commands
It is important to note that there is a lot more to the Angular CLI than simply instantiating, building and serving your project. The old ASP.NET developer, like me, might be tempted to use VS Code’s File menu to add new items to the application. In some cases you might create files manually, but for many types of Angular items you are going to want to let the Angular CLI to do the work for you. Adding certain types of items often requires adding and modifying multiple files. The Angular CLI is here to save us a considerable amount of time and headache.
An example of this would be adding a new component to our application. Lets say we want to add a new component called "about". To do this you would execute the following:
ng generate component about
This will add a new folder within the app
folder representing a new component. It will generate default/template code for a .css
, .html
, .spec.ts
, and .ts
file for this component. Additionally it will modify app.module.ts
to declare this new component.
A Quick Introduction to Angular Routing and Navigation
Not wanting to dig too deep into the rich features of Angular in this article, I feel that our time together here would be incomplete if I didn’t touch on Angular’s powerful routing capabilities. Routing is important for old ASP.NET developers who are used to writing applications that have mutiple “pages". In the world of ASP.NET MVC, we are used to having Controllers, Models, and Views to represent each page in our application. When it came to figuring out how to deal with multiple pages in Angular, my first thought was that our Index.html
was sort of like our Home.chtml
in MVC, and in order to create another page for something such as “About Us,” I would probably need to create an AboutUs.html
page. This didn’t feel right, especially since I became accustomed to thinking of the Index.html
more like our global layout/placeholder, so I asked my good friend and Angular expert, Wes Grimes about this. Wes told me to look at Routing. Well, it only took a quick scan at Angular’s official documentation on this, and I got really excited. While Routing in ASP.NET MVC is pretty slick, Routing in Angular steps up the game!
Angular’s implementation of routing is where you assign paths that map to various components. These are essentially our Views. The default app.component
becomes the container for everything. When our URL matches a defined path, the router “directs” to the app.component
, and replaces the contents inside the <router-outlet>
tag with the rendered contents of the mapped component. In addition to this, the part that really got me pumped was instead of using href
attribute in anchor tags (which you can do), we instead use the routerLink
attribute. When the user clicks the link, the mapped component is simply swapped out in the DOM via lazy loading and the browser’s URL changes! There is no browser redirecting, and only the mapped component section is refreshed. This makes the flow seamless, dramatically speeds up navigation between “pages”, and reduces the amount of content coming down the pipe. It truly gives the end user the perception that the entire application exists on the same page (Well, I guess technically it does, but you know what I mean.)
So let’s break this down. If we remember back to earlier when we first created our application, I said we should select “yes” when asked if we wanted to set up Routing. This is where we are going to put this to use.
Lets say we have a few components created to represent several pages. We will have a home component, an about component, and a page-not-found component. Within our app.module.ts
file, just under the import
lines, add the following:
const appRoutes: Routes = [
{ path: 'about', component: AboutComponent },
{ path: 'home', component: HomeComponent },
{ path: '', component: HomeComponent },
{ path: '**', component: PageNotFoundComponent }
];
Notice the path values for each of these components. The 'about' and 'home' paths should be fairly obvious, but what about the '' path, and the path specified for the PageNotFoundComponent? As far as the '' path, this just means that if no particular path is defined, then route to the home component. As for the **
path, this simply means that if any other path is given that does not match one of the above, then route to the page-not-found component.
Next, within the @NgModule
area we want to add the following within the imports
section:
RouterModule.forRoot(
appRoutes
)
So it will look like this:
@NgModule({
declarations: [
AppComponent,
PageNotFoundComponent,
AboutContentComponent,
HomeContentComponent
],
imports: [
RouterModule.forRoot(
appRoutes
),
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
Lastly, go to your app.component.html
and place the following tag wherever it is you would like your home, about, and page not found components to render.
<router-outlet></router-outlet>
At this point, wherever you wish to place a link in any of your HTML, instead of using the standard anchor tag markup, it is going to look a little different. Lets say that we want to place a link to the about "page," our markup will look like the following:
<a routerLink="about" routerLinkActive="active">About Us</a>
Navigation is as simple as that!
Building for Deployment
For the last part of this article, I want to show you how to do an official build for deployment. There is so much more you can do, but lets wrap up this particular app.
We can always run our application locally with the ng serve
command, but when it comes time to deploy our application, we need to perform a build. To do so, execute one of the following Angular CLI commands:
ng build --prod
or
ng b --prod
This will create a folder on the root called “dist”. This will contain your compiled application. The Angular CLI uses a JavaScript module bundler called Webpack. It compiles everything down to what the browsers understands: HTML, CSS, and JavaScript.
At this point, you might think that you can simply use file explorer to browse to C:\Temp\my-app\dist\my-app
and double-click the Index.html
to see the application work, however when you do, you will likely see a blank page. The index.html loaded, but the JavaScript didn’t execute.
The problem here resides with base-href mapping. If your application was sitting on the root of the system, the above build would run, however because it resides in a subfolder on the system, you need to specify the base-href location in the build command:
ng build --base-href "C:\Temp\my-app\dist\my-app\" --prod
Keep in mind that this also applies when deploying to a web server.
Summary
It is my hope that if you are an old ASP.NET MVC developer like me, who has been on the fence about checking out Angular, this article has given you some insight as to how things work, and helped to build some confidence in diving in to some Angular development. I am planning on a Part II in the near future. With this I will go into more depth with some things that you can do within your components.
Top comments (6)
Great article for .net pros who wants to make a switch to angular.
Excellent article, Corey!
Really appreciate the attention to detail and all the wonderful parallels drawn between Angular and .Net MVC.
Looking forward to a part 2! :)
As a long years nodejs developer I'd recommend using NVM tool instead of downloading node.js executables by hand. Because in just a year your node v10 is going to be unsupported and deprecated.
I second this. I've been using NVM for a handful of years now. Super easy to switch between LTS versions.
Great tip, thanks!
Great explanation article for Asp.net core+Angular beginners.