Learn Angular: A Comprehensive Guide with Examples(Covering Core Concepts, Advanced Topics, and Best Practices)

Part 1: Introduction to Angular

What is Angular?

Learn Angular: Angular is a TypeScript-based framework for building dynamic, single-page web applications (SPAs). Developed by Google, it provides tools for creating reusable components, managing state, and handling routing, forms, and HTTP communication.

Angular 19: Elevating Web Development with Enhanced Performance

Key Features:

  • Component-based architecture.
  • Two-way data binding.
  • Dependency injection.
  • Directives and pipes.
  • Robust CLI for scaffolding.

Why Learn Angular?

  • Enterprise-Ready: Used by companies like Microsoft, Forbes, and BMW.
  • Full-Featured: Built-in solutions for routing, forms, and HTTP.
  • TypeScript Support: Static typing for fewer runtime errors.

Part 2: Setting Up Angular

Install Angular CLI

npm install -g @angular/cli

Create a New Project

ng new my-app
cd my-app
ng serve --open

Project Structure


src/
├── app/
│ ├── app.component.ts # Root component
│ ├── app.module.ts # Root module
├── assets/ # Static files
├── index.html # Main HTML file
├── main.ts # Bootstraps the app

Part 3: Components & Templates
Creating a Component

ng generate component user

user.component.ts

typescript
@Component({
selector: 'app-user',
template: <h2>Welcome {{ username }}!</h2>,
})
export class UserComponent {
username = 'Alice';
}

Data Binding

1. Interpolation: `{{ value }}`

Score: {{ score }}

2. Property Binding: `[property]=”value”`

<button [disabled]="isDisabled">Submit</button>  

3. Event Binding: `(event)=”handler()”`

<button (click)="onSave()">Save</button>  

4. Two-Way Binding: `[(ngModel)]=”value”`

Part 4: Directives & Pipes

1. Structural Directives (Change DOM layout):

*ngIf:

<div *ngIf="isLoggedIn">Welcome back!</div>    

*ngFor:

<li *ngFor="let item of items">{{ item.name }}</li>   

2. Attribute Directives (Change element appearance/behavior):

ngClass:

<div [ngClass]="{ 'active': isActive }"></div> 

ngStyle:

<div [ngStyle]="{ 'font-size': fontSize + 'px' }"></div> 

Pipes (Transform Data)

Built-in Pipes:

{{ date | date:'shortDate' }}
{{ text | uppercase }}

Custom Pipe:

@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
 {{ 'hello' | reverse }}   <!-- Output: olleh -->  

Part 5: Dependency Injection & Services

What is Dependency Injection (DI)?

Learn Angular DI is a design pattern where a class receives dependencies from an external source (e.g., Angular injector) instead of creating them itself.

Creating a Service

ng generate service data

data.service.ts

@Injectable({ providedIn: 'root' })
export class DataService {
private apiUrl = 'https://api.example.com/data';

constructor(private http: HttpClient) {}

getData() {
return this.http.get(this.apiUrl);
}
}

Using a Service in a Component

export class UserComponent {
data: any;

constructor(private dataService: DataService) {}

ngOnInit() {
this.dataService.getData().subscribe(res => this.data = res);
}}

Part 6: Routing & Navigation

Learn Angular Setting Up Routes
app-routing.module.ts

const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'users', component: UserListComponent },
{ path: 'users/:id', component: UserDetailComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];

Router Outlet & Navigation

app.component.html

<nav>  
  <a routerLink="/home">Home</a>  
  <a routerLink="/users">Users</a>  
</nav>  
<router-outlet></router-outlet>

Accessing Route Parameters

export class UserDetailComponent {
constructor(private route: ActivatedRoute) {}

ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
}
}

Part 7: Forms

Template-Driven Forms

export class LoginFormComponent {
user = { email: '', password: '' };

onSubmit() {
console.log(this.user);
}
}

Template

<form #loginForm="ngForm" (ngSubmit)="onSubmit()">  
  <input name="email" ngModel required>  
  <input name="password" type="password" ngModel>  
  <button type="submit">Login</button>  
</form> 

Reactive Forms

export class SignupFormComponent {
form = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', Validators.minLength(8))
});

onSubmit() {
console.log(this.form.value);
}
}

Part 8: HTTP Client & Interceptors

HTTP GET Request

export class DataComponent {
data: any;

constructor(private http: HttpClient) {}

ngOnInit() {
this.http.get('https://api.example.com/data').subscribe(res => {
this.data = res;
});
}
}

HTTP Interceptor

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler) {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer token')
});
return next.handle(authReq);
}
}

Part 9: State Management with NgRx

NgRx Core Concepts

Actions: Events triggering state changes.
Reducers: Pure functions handling state transitions.
Selectors: Retrieve slices of state.
Effects: Handle side effects (e.g., API calls).

Example: Counter App

counter.actions.ts

export const increment = createAction('[Counter] Increment');

counter.reducer.ts

export const counterReducer = createReducer(
initialState = 0,
on(increment, state => state + 1)
);

Part 10: Testing

Learn Angular Testing Components with Jasmine

describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UserComponent]
}).compileComponents();
});

it('should display username', () => {
fixture.detectChanges();
const el = fixture.nativeElement.querySelector('h2');
expect(el.textContent).toContain('Alice');
});
});

Testing Services

describe('DataService', () => {
let service: DataService;
let httpMock: HttpTestingController;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule]
});
service = TestBed.inject(DataService);
httpMock = TestBed.inject(HttpTestingController);
});

it('should fetch data', () => {
service.getData().subscribe(res => {
expect(res).toEqual(mockData);
});
const req = httpMock.expectOne('https://api.example.com/data');
req.flush(mockData);
});
});

Part 11: Deployment

Build for Production

ng build --prod

Deploy to Firebase

1. Install Firebase CLI:

npm install -g firebase-tools

2. Deploy:

firebase login
firebase init
firebase deploy

Part 12: Advanced Topics

1. Lazy Loading Modules:

{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }

2. Server-Side Rendering (SSR) with Angular Universal:

ng add @nguniversal/express-engine

3. Angular Elements:

@Directive({ selector: 'app-widget' })
export class WidgetComponent implements OnInit {
// Convert component to a custom element
}

Part 13: Best Practices

  1. Modular Architecture: Split features into modules.
  2. Lazy Loading: Reduce initial bundle size.
  3. Change Detection Strategy: Use OnPush for performance.
  4. Immutable Data: Avoid direct state mutations.

Conclusion

Angular is a powerful framework for building scalable applications. By mastering components, services, routing, and state management, you can create robust SPAs. Practice with real projects, explore advanced topics like NgRx and SSR, and follow best practices for maintainable code.

Next Steps:

  • Build a CRUD app with Angular and Firebase.
  • Explore Angular Material for UI components.
  • Join Angular communities (e.g., Reddit, Discord).

Let me know if you’d like a deeper dive into any specific topic!

Share.

Welcome to Dastgeertech Studio! We are a dynamic and innovative tech company based in Lahore, Pakistan. At Dastgeertech Studio, we are dedicated to providing cutting-edge technology solutions tailored to meet the unique needs of our clients.

Discover more from DastgeerTech Studio

Subscribe now to keep reading and get access to the full archive.

Continue reading

Exit mobile version