So, do you want to learn the fundamentals of Angular 4 in a quick and easy way? You have come to the right place! You don’t need familiarity with any previous versions of Angular. In this tutorial, I’m going to take you from the ground up and show you Angular 4 in action. You only need a basic familiarity with HTML, CSS, and JavaScript.
If you learn better by videos, you can also watch this tutorial on YouTube; otherwise, continue reading.
Beginner’s questions
Let’s start with a few beginner’s questions. If you’ve used any previous versions of Angular, feel free to skip this section and jump to “Getting the tools”.
What is Angular?
Angular is a framework for building client applications in HTML, CSS, and either JavaScript or a language like TypeScript that can be compiled (more accurately, transpiled) to JavaScript. If you have never worked with TypeScript before, don’t worry. I will give you the basics in order to complete this tutorial.
What is TypeScript?
TypeScript is a superset of JavaScript. That means any valid JavaScript code is valid TypeScript code. But many prefer TypeScript because it has additional features that we don’t have in the current version of JavaScript that most browsers understand. So, when building Angular applications, we need to have our TypeScript code converted into JavaScript code that browsers can understand. This process is called transpilation which is the combination of translate and compile. And that’s the job of the TypeScript compiler.
Why do I need a framework like Angular?
A common question a lot of beginners ask me is: “Why do we need Angular in the first place? What’s wrong with the plain old vanilla JavaScript and jQuery?”.
There is nothing inherently wrong with using vanilla JavaScript/jQuery. In fact, a lot of web applications out there are built this way. But as your application grows, structuring your code in a clean and maintainable and more importantly, testable way, becomes harder and harder. I’m not saying this is impossible. But using a framework like Angular, makes your life far easier. Sure, there is a learning curve involved, but once you master Angular, you’ll be able to build client applications faster and easier.
Is Angular better than React/Vue.js?
These days there is a lot of debate between Angular vs React vs Vue.js. Whether Angular is better than React or Vue.js depends on how you define “better”. Each of these frameworks have strengths and weaknesses and there is no one shiny framework that makes every developer in the world happy. My suggestion to you is to learn the fundamentals of each of these frameworks and choose the one that works best for each project depending on its requirements.
Getting the tools
Now, let’s get dive into some code and get our hands dirty! The first thing you need to install is the latest version of Node. So, if you haven’t installed Node, head over to nodejs.org, and install the latest stable version.
Node comes with a tool called Node Package Manager or NPM, which is used for installing third-party libraries. In this tutorial, we’re going to use NPM to install Angular CLI. That is a command-line tool we use to create a new Angular project. It is also used for generating some boilerplate code during development (such as components, services, etc) as well as building an application for deployment. We do all this in the terminal.
So, once again in the Terminal, run the following command to install Angular CLI:
npm install -g @angular/cli
The -g flag stands for global. If you don’t put -g here, Angular CLI will be installed only in the current folder, and it’s not going to be accessible anywhere else.
If you’re on Mac, you need to put sudo at the beginning of this command to execute it as an administrator; otherwise, you’ll get permission errors.
Your First Angular App
So with Angular CLI in place, now we can create a new Angular project using the following command:
ng new hello-world
As you can see, we can access Angular CLI using ng. We provide a command (in this case new) to instruct Angular CLI on what we want it to do for us. Here, we are telling Angular CLI to generate a new project called “hello-world” and store it in a folder with the same name. We’ll be looking at these generated files shortly. For now, let’s finish the first step and see our new Angular app in the browser.
So, run the following commands in the terminal:
cd hello-world
npm install
ng serve
With the second command (npm install) we install all the dependencies of our application. The last command (ng serve) compiles our application and hosts it using a lightweight web server. Now, we can access our application at http://localhost:4200.
So, open up your browser and navigate to this address. You should see the following page:
Congratulations! You generated and served your first Angular 4 application. Now, let’s have a quick look at the files and folders in our new Angular project.
Structure of Angular Projects
Inside the generated folder, you’ll find the following top-level folders:
- e2e: includes end-to-end tests.
- node_modules: all the third-party libraries that our project is dependent upon.
- src: the actual source code of our Angular application.
99.9% of the time you’ll be working with the files inside the src folder. But let’s quickly overview the other files we have in this project:
angular-cli.json: a configuration file for Angular CLI. We use this file to import third-party stylesheets or define additional environments (eg testing environment) for our application.
package.json: a standard file for Node-based projects. It contains metadata about our project, such as its name, version as well as the list of its dependencies.
protractor.conf.js: Protractor is a tool for running end-to-end tests for Angular projects. We hardly need to modify this file.
karma.conf.js: Karma is a test runner for JavaScript applications. This file contains some configuration for Karma. We rarely need to modify this file.
tsconfig.json: includes setting for the TypeScript compiler. Again, we hardly, if ever, need to modify this file.
tslint.json: includes the settings for TSLint which is a popular tool for linting TypeScript code. That means it checks the quality of our TypeScript code based on a few configurable parameters. This is especially important in a team environment to ensure that everyone follows the same conventions and produces code of the same quality. We can run linting on our code using Angular CLI in the terminal or we can add it to our editor as a plug-in.
So, as you see, all these files are configuration files that work smoothly out of the box. Unless you want to customize them for your specific environment, you don’t ever have to modify them.
Architecture of Angular Apps
Ok, so you’ve learned how to generate and serve a new Angular project. You’ve also learned about various files and folders in a new Angular project. Now, let’s look at the architecture of Angular applications.
The most fundamental building block in an Angular application is a component. You can think of a component as a view component. It represents a view or part of a view (what the user sees). A component consists of three pieces:
- HTML markup: to render that view
- State: the data to display on the view
- Behavior: the logic behind that view. For example, what should happen when the user clicks a button.
A component can contain other components. For example, let’s imagine you’re going to build a web app like Twitter using Angular. In your implementation, you may have a tree of component likes this:
- App
- NavBar
- SideBar
- ContentArea
- Tweets
- Tweet
- Like
- Tweet
- Tweets
Now, at the root of the application, we have a component called AppComponent. This is the root of every Angular application. Our AppComponent contains 3 child components: NavBar, SideBar, and ContentArea.
The reason for such separation is because the navigation bar is logically a separate part of the view. It has its own markup, state, and behavior. We can encapsulate all that using a component called NavBarComponent. This way, when modifying or extending the navigation bar of our application, we can focus on a small component with a lightweight template.
Benefits of Component-based Architecture
As you can see, this component-based architecture makes our applications more organized and maintainable. Plus, we can potentially reuse these components in various parts of an application or in an entirely different application. For example, tomorrow, we can grab this NavBarComponent and put it in an entirely different project. We just need to modify the links. But all the HTML markup will remain the same.
Back to our tree of components, you can see that inside the content area, we have a tree of components like this:
- Tweets
- Tweet
- Like
- Tweet
Again, this is one way to model this. We don’t necessarily have to have a separate component for the list of tweets and each tweet. We could combine TweetsComponent and TweetComponentinto one component. But, I’d like to separate the LikeComponent because we could potentially reuse this like button somewhere else in this application or in another application. Even if we don’t reuse it, separating the markup, state and behavior of this like button into a separate component, makes our application more maintainable and testable.
An Angular Component in Action
Now, let’s inspect a real component in action.
Back to our project, open up the src/app folder. Inside this folder, you should see the following files:
- app.component.css
- app.component.html
- app.component.spec.ts
- app.component.ts
- app.module.ts
These files represent AppComponent, which is the root component for our application. In this particular case, all these files are inside the app folder. But when we generate a new component using Angular CLI, all the files that make up a component will be grouped by a folder.
So, in terms of the implementation, each component in an Angular project is physically implemented using four files:
- A CSS file: where we define all the styles for that component. These styles will only be scoped to this component and will not leak to the outside. This is what Shadow DOM does. But not all browsers today support Shadow DOM. So, Angular uses a technique to emulate the Shadow DOM.
- An HTML file: contains the markup to render in the DOM.
- A spec file: includes the unit tests.
- A TypeScript file: where we define the state (the data to display) and behavior (logic) of our component.
You will also see an app.module.ts file. This file defines the root module of our application and tells angular how to assemble the app.
Creating a Component
Now that you know what a component is, let’s use Angular CLI and add a new component to this application.
Imagine we want to build an e-commerce application. On the home page, we’re going to display the list of products and below each product, we want to have a button for adding that product to the shopping cart.
So, for this exercise, we want to create a super simple component to represent each product on the home page. This component will include the HTML markup to display that product, and it’ll respond to the click event of a button to add that product to the shopping cart.
When we click this button, it also shows the number of products of this type in the shopping cart. Initially, the number should be 0. Every time we click the Add to Shopping Cart button, the number is increased. Of course, in a real-world application, there’s far more complexity involved. For example, we may want to call some back-end services to store this item in a database. But for now, let’s just focus on the fundamentals. If you understand the fundamentals well, you can always add these other details later. So, for now, forget about the server-side, databases and other complexities.
Ok, we’re ready to create a component. We can manually create all those four files by hand, but there is a faster way. We can use Angular CLI!
Generating a Component Using Angular CLI
Run the following command in the terminal, inside the project folder:
ng g c product
Here, g is short for generate, c is short for component and product is the name of our component. Now, if you look at the project folder, inside the src/app folder, you should see a new folder called product. Expand this folder. You should see the following files:
- product.component.css
- product.component.html
- product.component.spec.ts
- product.component.ts
Open product.component.ts. This is what you should see:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
constructor() { }
ngOnInit() {
}
If this code looks complex to you, don’t worry! I’m going to make it super simple. It’s actually far easier than you may think!
For now, I want you to note the value of the selector property. It’s app-product. This is a CSS selector. So app-product represents an element by this name. With this, we can extend the HTML vocabulary. Anywhere we add this app-product element, Angular will render the HTML markup of ProductComponent inside that element. So, let’s add this element to the template for our AppComponent.
Using a Component
Open up src/app/app.component.html. Replace all the markup with the following:
<app-product></app-product>
Now, our application includes a tree of components:
- App
- Product
At the root of this tree, we have our AppComponent. This component includes a child component: ProductComponent.
Save the changes. Back to the browser, now, you should see this:
Our ProductComponent has a simple template that includes “product works!”. We can modify product.component.html and add some complex markup here. For example, we can use Bootstrap 4 cards to render the product inside a card.
But for now, we don’t want to waste our time and make our application pretty. Our focus is on understanding Angular. We can always come back to the template for ProductComponent and improve it.
Examining an Angular Component
You successfully generated and used a component. Now, let’s examine this component in detail. So, open up product.component.ts. Here is the code for reference:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
constructor() { }
ngOnInit() {
}
Inside of this file, we have a TypeScript class called ProductComponent.
What is a Class?
A class is a fundamental building block of many object-oriented programming languages. It’s a container for a bunch of related functions and variables.
So, unlike vanilla JavaScript where all our functions and variables are hanging from the global namespace, we put them in containers called classes. With these classes, we don’t pollute the global namespace and as a result, we won’t have one function overwriting another function with the same name. Because these functions are now in separate containers (classes). Also, because each class includes a bunch of highly related functions and variables, our code is more organized and maintainable.
In object-oriented programming terms, we call these functions and variables that reside in a class, methods and fields/properties respectively. Fields and properties are technically different but they are often used interchangeably. A field is like a variable where we store some data. A property looks like a field from the outside, but internally, it is a function around a field that gives us read or write access to that field. If this sounds confusing, don’t worry about it now. I’m planning to publish a separate post about TypeScript. For now, you can assume fields and properties are the same, even though they are not!
Example of a Class
So, in product.component.ts, we have a class called ProductComponent. This class has 2 functions (methods): constructor and ngOnInit.
export class ProductComponent implements OnInit {
constructor() { }
ngOnInit() {
}
Constructor is a reserved keyword in TypeScript. A method by that name is a special method in a class. This method is called automatically when we create an instance of that class.
ngOnInit is a special method in Angular. Angular calls this method when it creates an instance of this component and displays it to the user in the browser.
For this exercise, we don’t have to worry about either of these methods. So, delete both of them. You should also delete implements OnInit in front of the class name. For now, don’t worry about it, but basically, it tells Angular that this class has some initialization code that should be executed before this component is displayed to the user.
So, your code should look like this:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent {
}
Component Metadata
So, you’ve seen that we implement a component using a TypeScript class. But a class on its own is just a class. It only includes some data and logic for a view. It doesn’t include any HTML markup or CSS styles. In order to attach these to this class, we need to promote this class to a component. We can do this by using the @Component() decorator function on top of this class (lines 3-7):
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent { }
With this, we can attach metadata to this class that Angular understands. This @Component()decorator function is defined in Angular and you can see we’re importing it on line 1. It takes an object with the following properties:
- selector
- templateUrl
- styleUrls
You’ve seen the selector in action. It associates a new HTML element to this component. With this, we can extend the standard HTML vocabulary. So, now we have a new custom element (app-product) that we can use anywhere in our application. When Angular sees that element, it’ll place the HTML markup of our ProductComponent inside that element.
The other 2 properties (templateUrl and styleUrls) are self-explanatory. They specify the path to the HTML template and CSS file(s) for this component.
Property Binding
In Angular, unlike vanilla JavaScript or jQuery, we don’t work directly with the DOM. So, we don’t write code like this:
$("#myElement").text("something")
Instead, we use property binding. Let me show you how that works.
In our ProductComponent, let’s add a new field:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent { title = 'USB Stick 8GB'; }
This title field contains the title for our product. In a real-world scenario, we get this title from a database somewhere on the server. So we don’t hardcode it here. But for now, let’s not worry about this and see property binding in action.
Now, open up product.component.html. Replace all the markup there with:
<p>{{ title }}</p>
This special double curly brace syntax you see here is what we call interpolation in Angular. Fancy name again, right? This basically tells Angular to replace what we have between curly braces with the value of the title field in our component.
This syntax is a shorthand for the actual property binding syntax we have in Angular. The code you wrote above is equivalent to the following code:
<p [innerHtml]="title"></p>
What is this? Very simple! In vanilla JavaScript, we can simply get a reference to an element in the DOM and set its innerHTML property like this:
var el = document.getElementById("myElement");
el.innerHTML = "USB Stick 8GB";
So, every DOM element has a property called innerHTML. In our Angular application, we’re using the square bracket syntax to bind a property of a DOM element to a field/property in our component:
<p [innerHtml]="title"></p>
So, at run-time, Angular will set the innerHtml property of this paragraph to the title field we defined in our component. And more importantly, if the value of our title field changes in the future, Angular will automatically update the view (DOM) for us! This is property binding in action. We have bound the innerHTML property of this element to the title field of our ProductComponent.
A Simple Exercise
Now, here is a simple exercise for you. I want you to extend our product component and display the number of USB sticks in the shopping cart below the name of this product. So, stop reading and make any necessary changes in the code. Then, come back here and see my solution.
Ok, so you should have added a new field in ProductComponent:
export class ProductComponent { title = "USB Stick 8GB"; itemCount = 0; }
And used interpolation or property binding syntax to render it in the template:
<p>{{ title }}</p>
<p>{{ itemCount }}</p>
Event Binding
Similar to property binding, we have another concept in Angular called event binding. With property binding, we bind properties of DOM elements to fields/properties in our component. With event binding, we bind events of DOM elements (such as clicks) to methods in our component. So, for example, when the user clicks on a button, a method in our component will be called.
We’re going to extend our product component and add a button to increase the number of USB sticks in the shopping cart. So, modify product.component.html as follows:
<p>{{ title }}</p>
<p>{{ itemCount }}</p>
<button (click)="addItem()">Add</button>
Note the difference between property and event binding syntax. We use square brackets for property bindings and parenthesis for event binding. With this code, whenever our button is clicked, Angular calls the addItem() method in our component.
So, let’s implement this method in our component. Open up product.component.ts:
export class ProductComponent { title = "USB Stick 8GB"; itemCount = 0; addItem() { this.itemCount++; } }
Here, we’re simply incrementing the itemCount field. Now, save the changes and go back to the browser. Test this application by clicking the Add button. You can see the count gets updated immediately. This is the beauty of property and event binding in action!
As I explained, Angular watches our itemCount field. When its value gets changed, Angular updates the DOM immediately.
What you’ve seen far is just the tip of the iceberg. There is far more to property and event binding and Angular in general. It’s impossible to cover it all in one blog post. If you’re serious about learning Angular, I have a complete course with 30 hours of high-quality videos. This is equivalent to a book with more than a thousand pages!
Recap
Let’s quickly recap what you’ve learned in this post:
- Angular is a framework for building client apps with HTML, CSS and TypeScript.
- It gives our applications a proper, maintainable and testable structure.
- At the core of every Angular application, we have a tree of components.
- Each component encapsulates the state (data), the HTML markup and the behavior for a view.
- At a minimum, a component is implemented using a class. This class may include a bunch of fields for displaying data and methods, which will be called in response to events raised from the DOM events.
- A component may have an external template stored in a separate HTML file.
- It may also include one or more external stylesheets.
- A component also has a selector. That tells Angular where in the DOM to place this component.
- We use the property binding syntax (square brackets) to bind properties of DOM elements to fields/properties in our components.
- When the value of these fields/properties change, Angular automatically updates the DOM (view).
- We use the event binding syntax (parenthesis) to bind events of DOM elements to methods in our component.
- Angular automatically calls these methods to handle events raised from the DOM elements.
Once again, if you want to learn everything about Angular from the basic to the advanced topics, I encourage you to enroll in my complete Angular course. This is far easier and faster than jumping from one tutorial to another. With this course, you can learn all these concepts in one place, step-by-step and you’ll build and deploy real e-commerce app with Angular and Firebase at the end of the course.
If you’ve enjoyed this tutorial, please show the love by sharing it with others. Thank you!
2. Then ‘ng init’ to setup angular in our folder
3. Then ng app <> to create a new app
4. ‘ng serve’ to run
You cannot use the new command inside an Angular CLI project.
Kailash
verbose node v8.10.0
15 verbose npm v5.6.0
16 error code ENOTFOUND
17 error errno ENOTFOUND
18 error network request to https://registry.npmjs.org/cordova failed, reason: getaddrinfo ENOTFOUND proxy.yourcorp.com proxy.yourcorp.com:811
} // <– this one here
constructor() { }
}