Building a Professional Angular 19 App Using Signals and Services
In this article, we will build a professional-grade example using: ✅ Angular 19 ✅ Signals ✅ Dependency Injection (Services) ✅ Standalone Components Goal We will create: A service that manages a list of heroes using signal(). A component that displays and adds heroes via the service. Clean, reactive, and fully Angular 19-compliant code. Setting up the Service: HeroService import { Injectable, signal } from '@angular/core'; export interface Hero { id: number; name: string; } @Injectable({ providedIn: 'root' }) export class HeroService { private heroes = signal([ { id: 1, name: 'Goku' }, { id: 2, name: 'Vegeta' } ]); getHeroes() { return this.heroes; } addHero(hero: Hero) { this.heroes.update(prev => [...prev, hero]); } removeHero(id: number) { this.heroes.update(prev => prev.filter(h => h.id !== id)); } } Building the Component: HeroListComponent import { Component } from '@angular/core'; import { HeroService } from './hero.service'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; @Component({ selector: 'app-hero-list', standalone: true, template: ` Hero List {{ hero.name }} Remove Add Hero `, imports: [CommonModule, FormsModule] }) export class HeroListComponent { heroes = signal([]); newHeroName = ''; constructor(private heroService: HeroService) { this.heroes = this.heroService.getHeroes(); } add() { if (this.newHeroName.trim()) { const newHero = { id: Date.now(), name: this.newHeroName.trim() }; this.heroService.addHero(newHero); this.newHeroName = ''; } } remove(id: number) { this.heroService.removeHero(id); } } How It Works Layer Purpose Service (HeroService) Owns the signal, responsible for all state Component (HeroListComponent) Subscribes to the signal and reacts automatically Template Renders reactive values via heroes() call When you call addHero() or removeHero(), the signal updates and the component auto-renders without manual refresh. Key Best Practices Services manage signals, components consume them. No manual subscriptions needed. Keep services pure and encapsulated. Use standalone components for cleaner architecture. Final Thoughts Angular 19 is leading towards a lightweight, reactive, modular future. Using Signals and Services properly will make your apps: Faster More maintainable Highly scalable Use Signals for state, Services for management, and Standalone Components for architecture. Happy coding with Angular 19! ⚡

In this article, we will build a professional-grade example using:
- ✅ Angular 19
- ✅ Signals
- ✅ Dependency Injection (Services)
- ✅ Standalone Components
Goal
We will create:
- A service that manages a list of heroes using
signal()
. - A component that displays and adds heroes via the service.
- Clean, reactive, and fully Angular 19-compliant code.
Setting up the Service: HeroService
import { Injectable, signal } from '@angular/core';
export interface Hero {
id: number;
name: string;
}
@Injectable({ providedIn: 'root' })
export class HeroService {
private heroes = signal<Hero[]>([
{ id: 1, name: 'Goku' },
{ id: 2, name: 'Vegeta' }
]);
getHeroes() {
return this.heroes;
}
addHero(hero: Hero) {
this.heroes.update(prev => [...prev, hero]);
}
removeHero(id: number) {
this.heroes.update(prev => prev.filter(h => h.id !== id));
}
}
Building the Component: HeroListComponent
import { Component } from '@angular/core';
import { HeroService } from './hero.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-hero-list',
standalone: true,
template: `
Hero List
-
{{ hero.name }}
`,
imports: [CommonModule, FormsModule]
})
export class HeroListComponent {
heroes = signal<Hero[]>([]);
newHeroName = '';
constructor(private heroService: HeroService) {
this.heroes = this.heroService.getHeroes();
}
add() {
if (this.newHeroName.trim()) {
const newHero = { id: Date.now(), name: this.newHeroName.trim() };
this.heroService.addHero(newHero);
this.newHeroName = '';
}
}
remove(id: number) {
this.heroService.removeHero(id);
}
}
How It Works
Layer | Purpose |
---|---|
Service (HeroService) | Owns the signal , responsible for all state |
Component (HeroListComponent) | Subscribes to the signal and reacts automatically |
Template | Renders reactive values via heroes() call |
When you call addHero()
or removeHero()
, the signal updates and the component auto-renders without manual refresh.
Key Best Practices
- Services manage signals, components consume them.
- No manual subscriptions needed.
- Keep services pure and encapsulated.
- Use standalone components for cleaner architecture.
Final Thoughts
Angular 19 is leading towards a lightweight, reactive, modular future. Using Signals and Services properly will make your apps:
- Faster
- More maintainable
- Highly scalable
Use Signals for state, Services for management, and Standalone Components for architecture.
Happy coding with Angular 19! ⚡