DEV Community

Cover image for Angular 17+ Fundamentals : Everything you need to know in one place
Gaurav
Gaurav

Posted on

Angular 17+ Fundamentals : Everything you need to know in one place

If you're here, you're probably already interested in learning Angular and want to dive right into the fundamentals. There's no need to convince you why Angular is a powerful framework—you're likely aware of its popularity for building scalable, single-page applications. This guide is all about getting hands-on with Angular, so we’ll skip the sales pitch and jump straight into the essentials.

From setting up routing to handling complex data flows with signals, computed values, and deferrable views, this post will guide you through the key concepts you'll need to build dynamic, efficient Angular applications. Whether you're just getting started or need a quick refresher, I’ve got you covered with practical examples and explanations for every topic.

Let’s dive in!

Table of Contents

  • Routing
  • Standalone Components
  • Forms
  • Property Binding
  • Event Handling
  • Conditional Rendering
  • For Loops in Angular
  • Passing Data Between Components
  • Reactive Primitives: Signals, Computed, and Effects
  • Deferrable Views

1. Routing

Routing allows you to navigate between different views in an Angular app. Here’s how routing is set up in Angular 17:



import { Routes } from '@angular/router';
import { BasicsComponent } from './basics/basics.component';
import { HomeComponent } from './home/home.component';
import { UserCardViewComponent } from './user-card-view/user-card-view.component';
import { OutputComponentComponent } from './output-component/output-component.component';

export const routes: Routes = [
    {
        path: 'basics',
        component: BasicsComponent
    },
    {
        path: '',
        component: HomeComponent
    },
    {
        // Passing data in the component from the URL
        path: 'user-card-view/:username',
        component: UserCardViewComponent
    },
    {
        path: 'output-view',
        component: OutputComponentComponent
    }
];



Enter fullscreen mode Exit fullscreen mode

Description:

  • Dynamic Routes: In the user-card-view/:username route, :username is a dynamic parameter passed from the URL to the component.
  • Empty Path (path: ''): Navigating to the root of the application will load HomeComponent.

2. Standalone Components

Angular 17 introduced standalone components, making them more modular and independent. You can import other modules or components directly into a standalone component.



import { Component } from '@angular/core';
import { UserCardViewComponent } from '../user-card-view/user-card-view.component';
import { Router, RouterLink } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@Component({
  selector: 'app-basics',
  standalone: true,
  imports: [UserCardViewComponent, RouterLink, FormsModule, ReactiveFormsModule],
  templateUrl: './basics.component.html',
  styleUrls: ['./basics.component.css']
})
export class BasicsComponent {
  // Component logic goes here
}



Enter fullscreen mode Exit fullscreen mode

Description:

  • Standalone components reduce the dependency on Angular modules and allow for more modular development. You can directly import other components, directives, and services into them.

3. Forms

Template-Driven Forms
Template-driven forms are quick to set up but are best for simpler use cases:



<form name="loginForm">
    <label for="username">Username:</label>
    <input type="text" name="username" [(ngModel)]="username">

    <label for="password">Password:</label>
    <input type="password" name="password" [(ngModel)]="password">
</form>

<p>Username: {{ username }}</p>
<p>Password: {{ password }}</p>



Enter fullscreen mode Exit fullscreen mode

Reactive Forms
Reactive forms are more powerful and scalable, especially for larger applications:



loginForm = new FormGroup({
    username: new FormControl(''),
    password: new FormControl('')
});

handleSubmit() {
    console.log(this.loginForm.value);
}

<form [formGroup]="loginForm" (ngSubmit)="handleSubmit()">
    <label for="username">Username:</label>
    <input formControlName="username">

    <label for="password">Password:</label>
    <input formControlName="password">

    <button type="submit">Submit</button>
</form>



Enter fullscreen mode Exit fullscreen mode

Description:

  • Template-driven forms are quick to implement but require more effort when adding validation.
  • Reactive forms are highly configurable, providing better control over form state and validation.

4. Property Binding

Property binding dynamically sets properties in the DOM. This is done using square brackets [ ].



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


Enter fullscreen mode Exit fullscreen mode

In the component:



isDisabled = true;


Enter fullscreen mode Exit fullscreen mode

Description:

  • Here, the button is disabled based on the value of isDisabled. Property binding updates the DOM property dynamically as the component's property changes.

5. Event Handling

Event binding allows you to respond to user interactions.



<button (click)="handleClick()">Submit</button>


Enter fullscreen mode Exit fullscreen mode

In the component:



handleClick() {
  console.log('Button clicked!');
}


Enter fullscreen mode Exit fullscreen mode

Description:

  • The event handler handleClick() is invoked whenever the button is clicked.

6. Conditional Rendering

If-Else Statements
You can control the visibility of elements using *ngIf.



@if(card.type === 'gold') {
    <span>Gold</span>
} @else if(card.type === 'silver') {
    <span>Silver</span>
} @else if(card.type === 'platinum') {
    <span>Platinum</span>
}


Enter fullscreen mode Exit fullscreen mode

Switch-Case
For complex conditions, you can use @switch to improve readability.



@switch(card.type) {
    @case('gold') {
        <span>Gold</span>
    }
    @case('silver') {
        <span>Silver</span>
    }
    @case('platinum') {
        <span>Platinum</span>
    }
    @default {
        <span>Unknown Type</span>
    }
}


Enter fullscreen mode Exit fullscreen mode

Description:

  • If-Else is used for simple conditionals.
  • Switch-Case is preferred when you need to handle multiple conditions, especially for readability and scalability.

7. For Loops in Angular

The @for directive lets you iterate over an array.



@for(item of cardList; track item) {
    <div class="card">
        <h5>{{item.name}}</h5>
        <p>{{item.number}}</p>
        <span>{{item.type}}</span>
    </div>
}


Enter fullscreen mode Exit fullscreen mode

Description:

  • trackBy improves performance by uniquely identifying each item, ensuring the DOM efficiently handles large lists.

8. Passing Data Between Components

You can pass data between parent and child components using @Input() and @Output()
Sending Data to Child Component



<app-user-card-view [userCardData]="card"></app-user-card-view>


Enter fullscreen mode Exit fullscreen mode

In UserCardViewComponent:



@Input() userCardData: CardModel;



Enter fullscreen mode Exit fullscreen mode

Sending Data Back to Parent



@Output() selectedCard = new EventEmitter<any>();
sendDataToAnotherComponent() {
  this.selectedCard.emit(this.cardList);
}


Enter fullscreen mode Exit fullscreen mode

Description:

  • @Input() allows a parent component to pass data to its child.
  • @Output() uses EventEmitter to send data from the child back to the parent component.

9. Reactive Primitives: Signals, Computed, and Effects

Angular 17 introduced Signals and Computed values for reactive programming.

Signals
Signals are reactive variables that automatically notify Angular when they change.



firstName = signal("Gaurav");


Enter fullscreen mode Exit fullscreen mode

Computed Values
Computed values derive from other reactive values (signals).

fullName = computed(() =>${this.firstName()} ${this.lastName()});

Effects
Effects allow you to react to changes in signals or perform side effects.

effect(() => console.log(Full Name: ${this.fullName()}));

Description:

  • Signals provide a reactive data model, reducing the need for manual change detection.
  • Computed Values derive new values from existing signals.
  • Effects are used to perform actions when signals change.

10. Deferrable Views

Deferrable views allow for lazy-loading parts of the UI, based on certain conditions or user interactions.

Basic Example



<button #trigger>Load More</button>

@defer (on interaction(trigger)) {
    <p>Content loaded.</p>
} @loading {
    <p>Loading...</p>
} @error {
    <p>Error loading content.</p>
}



Enter fullscreen mode Exit fullscreen mode

Advanced Example: Conditional Lazy Loading
You can defer loading content based on specific conditions:



<button (click)="counter = counter - 1">Make it Zero: {{counter}}</button>

@defer (when counter == 0) {
    <p>Content loaded when counter hits 0!</p>
} @placeholder {
    <p>Waiting for counter to hit 0...</p>
}



Enter fullscreen mode Exit fullscreen mode

Description:

  • Deferrable Views improve performance by delaying the loading of heavy components until necessary.
  • The @loading, @error, and @placeholder directives provide a better user experience by giving feedback during the loading process.

Conclusion
This guide walks you through key Angular concepts like routing, standalone components, forms, and reactive primitives. With Angular 17’s new features like signals and deferrable views, you can create more efficient and reactive web applications.

Connect with me:@ LinkedIn

Top comments (0)