Angular First App
Welcome to the exciting world of Angular development! In this tutorial, you'll learn how to create your very first Angular application step-by-step. By the end of this guide, you'll have a functioning Angular app running on your machine and understand the core building blocks of an Angular project.
Prerequisites
Before we begin, make sure you have:
- Node.js (LTS version recommended)
- npm (comes with Node.js)
- Basic knowledge of HTML, CSS, and JavaScript/TypeScript
Installing Angular CLI
The Angular CLI (Command Line Interface) is a powerful tool that helps us create, develop, and maintain Angular applications. Let's install it globally on your system:
npm install -g @angular/cli
After installation, you can check if everything is set up correctly:
ng version
You should see output showing the Angular CLI version along with related package versions.
Creating Your First Angular App
Now, let's create your first Angular application using the CLI:
ng new my-first-angular-app
During the setup process, the CLI will ask you a few questions:
- Routing: Select 'Yes' to include Angular's routing capabilities
- Stylesheet format: You can choose from CSS, SCSS, Sass, Less, or Stylus (for beginners, CSS is perfectly fine)
After answering these questions, the CLI will create a new project with all necessary files and install the required dependencies. This might take a few minutes.
Exploring the Project Structure
Let's navigate to our new project directory and take a look at the key files and folders:
cd my-first-angular-app
Here's what you'll find:
my-first-angular-app/
├── node_modules/ # Third-party libraries
├── src/ # Source code of your app
│ ├── app/ # App components, modules, services
│ ├── assets/ # Static assets (images, icons)
│ ├── environments/ # Environment configuration files
│ ├── index.html # Main HTML file
│ ├── main.ts # Entry point of the app
│ └── styles.css # Global styles
├── angular.json # Angular workspace configuration
├── package.json # Project dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── ... # Other config files
Key Files to Understand:
- src/app/app.module.ts: The root module that tells Angular how to assemble the application
- src/app/app.component.ts: The root component that controls the application view
- src/index.html: The main HTML page that gets displayed
- src/main.ts: The main entry point that bootstraps the Angular application
Running Your Application
Let's start the development server and see our application in action:
ng serve
After compilation completes, open your browser and navigate to http://localhost:4200/
. You should see your Angular application running!
The CLI includes a live reload server, so any changes you make to the source files will automatically trigger a rebuild and refresh the browser.
Understanding Your First Component
Components are the fundamental building blocks of Angular applications. Let's examine the root component that was automatically created:
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-first-angular-app';
}
This file defines a component with three main parts:
- selector: The HTML tag that will be used to insert this component (app-root)
- templateUrl: The HTML template file for this component
- styleUrls: The CSS styles for this component
The class AppComponent
contains properties and methods for the component. Here we have a single property title
that we can use in our template.
app.component.html
This is the template file that displays the component content. Let's modify it to create something personalized:
<div class="container">
<h1>Welcome to {{ title }}!</h1>
<p>This is my first Angular application.</p>
<div class="counter-section">
<h2>Simple Counter</h2>
<p>Current count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
</div>
Notice the double curly braces {{ }}
- this is Angular's interpolation syntax that binds component properties to the template.
Let's update our component to include the counter functionality:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-first-angular-app';
count = 0;
increment() {
this.count++;
}
decrement() {
if (this.count > 0) {
this.count--;
}
}
}
And let's add some simple styles in app.component.css:
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
h1 {
color: #3f51b5;
}
.counter-section {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-top: 20px;
}
button {
background-color: #3f51b5;
color: white;
border: none;
padding: 8px 16px;
margin-right: 8px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #303f9f;
}
Now when you run ng serve
, you'll see a simple counter application. The buttons increment and decrement the counter value, demonstrating Angular's data binding and event handling.
Creating a New Component
Let's create a new component to understand the process better:
ng generate component hello-world
This creates a new component in src/app/hello-world/
with four files:
hello-world.component.ts
hello-world.component.html
hello-world.component.css
hello-world.component.spec.ts
(for testing)
Let's modify the hello-world component:
hello-world.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-hello-world',
templateUrl: './hello-world.component.html',
styleUrls: ['./hello-world.component.css']
})
export class HelloWorldComponent implements OnInit {
message = 'Hello, Angular Developer!';
constructor() { }
ngOnInit(): void {
// Lifecycle hook that runs when the component initializes
console.log('HelloWorld component initialized');
}
}
hello-world.component.html
<div class="hello-container">
<h2>{{ message }}</h2>
<p>This is a separate component that can be reused throughout your application.</p>
<input type="text" [(ngModel)]="message" placeholder="Change the message">
</div>
For the two-way binding to work with [(ngModel)]
, we need to import the FormsModule
in our app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HelloWorldComponent } from './hello-world/hello-world.component';
@NgModule({
declarations: [
AppComponent,
HelloWorldComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule // Add this line
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
hello-world.component.css
.hello-container {
background-color: #e8f5e9;
padding: 15px;
border-radius: 8px;
margin-top: 20px;
}
input {
padding: 8px;
margin-top: 10px;
width: 100%;
max-width: 300px;
border: 1px solid #ccc;
border-radius: 4px;
}
Now, let's use this component in our app.component.html:
<div class="container">
<h1>Welcome to {{ title }}!</h1>
<p>This is my first Angular application.</p>
<div class="counter-section">
<h2>Simple Counter</h2>
<p>Current count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
<!-- Add our new component -->
<app-hello-world></app-hello-world>
</div>
Adding Basic Routing
Angular provides a powerful routing system that allows for creating Single Page Applications. Let's see how to use it.
First, let's create a new component that will act as another page:
ng generate component about
Update the about.component.html:
<div class="about-container">
<h1>About This App</h1>
<p>This is a simple Angular application created to demonstrate the basic concepts of Angular.</p>
<p>Version: 1.0.0</p>
<button routerLink="/">Back to Home</button>
</div>
Add some styles to about.component.css:
.about-container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
button {
background-color: #3f51b5;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
Now, let's set up the routing. Open app-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{ path: 'about', component: AboutComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Finally, let's modify our app.component.html to include navigation and the router outlet:
<div class="container">
<header>
<h1>{{ title }}</h1>
<nav>
<a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">Home</a>
<a routerLink="/about" routerLinkActive="active">About</a>
</nav>
</header>
<!-- This is where the routed components will be displayed -->
<router-outlet></router-outlet>
<!-- Only show these on the home path -->
<div *ngIf="router.url === '/'">
<div class="counter-section">
<h2>Simple Counter</h2>
<p>Current count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
<app-hello-world></app-hello-world>
</div>
</div>
You'll need to update the AppComponent to include the router:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-first-angular-app';
count = 0;
constructor(public router: Router) {}
increment() {
this.count++;
}
decrement() {
if (this.count > 0) {
this.count--;
}
}
}
And update the app.component.css to style the navigation:
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
nav {
display: flex;
gap: 15px;
}
nav a {
text-decoration: none;
color: #3f51b5;
padding: 5px 10px;
border-radius: 4px;
}
nav a.active {
background-color: #3f51b5;
color: white;
}
h1 {
color: #3f51b5;
margin: 0;
}
.counter-section {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-top: 20px;
}
button {
background-color: #3f51b5;
color: white;
border: none;
padding: 8px 16px;
margin-right: 8px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #303f9f;
}
Now you have a basic Angular application with:
- Multiple components
- Basic routing between pages
- Event handling
- Two-way data binding
- Component reuse
Building for Production
When you're ready to deploy your application, build it with:
ng build --prod
This creates optimized production files in the dist/
folder that you can deploy to any web server.
Summary
Congratulations! You've created your first Angular application from scratch. In this tutorial, we've covered:
- Installing the Angular CLI
- Creating a new Angular project
- Understanding the project structure
- Creating and using components
- Working with data binding and events
- Implementing basic routing
- Building for production
This is just the beginning of your Angular journey. Angular has many more powerful features like services, dependency injection, reactive forms, HTTP client, and much more.
Additional Resources
Here are some resources to continue learning:
- Official Angular Documentation
- Angular Tutorial: Tour of Heroes
- Angular CLI Commands Reference
- TypeScript Documentation
Exercises
To reinforce your learning, try these exercises:
- Add a "reset" button to the counter that sets the count back to zero
- Create a new component that displays a list of items (e.g., a to-do list)
- Add a form that allows users to add new items to the list
- Create another route for a "Contact" page
- Implement a service that shares data between components
Happy coding!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)