Skip to content

What Is a Service

Components handle the view: templates, user interactions, rendering logic. But not all code belongs in components. Business logic, data access, and shared state should live in services — TypeScript classes that components can inject and use.

Imagine a Home component and a Browse component that both need to fetch movies. Without services, each component would duplicate the API call logic — the URL construction, error handling, and type assertions. When the API changes, you update both.

With a service, the logic lives in one place:

movie.service.ts
@Injectable({ providedIn: 'root' })
export class MovieService {
getPopular(): Observable<Movie[]> { /* ... */ }
getTrending(): Observable<Movie[]> { /* ... */ }
getDetail(id: number): Observable<MovieDetail> { /* ... */ }
}

Home injects MovieService and calls getPopular(). Browse injects it and calls discover(). The API logic is written once, tested once, and used everywhere.

CinemaVault uses three services:

MovieService — all TMDb API calls. It handles URL construction, HTTP requests, and response typing. Components call its methods and receive typed Observables.

WatchlistService — manages the watchlist. It holds a signal<Movie[]> that NavBar, MovieCard, and Watchlist all read from the same source. When a movie is added or removed, every component that reads the signal updates automatically. It also syncs to localStorage so the watchlist persists across sessions.

ToastService — manages the toast notification. It holds a signal that Toast (always rendered in app.html) observes. Any component or guard can call toast.show('message') to display a notification without knowing how Toast renders it.

ComponentService
Manages a piece of the viewManages logic or state
Has a templateHas no template
Created and destroyed with the DOMTypically lives as long as the app
Communicates via inputs/outputsCommunicates via method calls and signals/observables

The rule of thumb: if logic or state needs to be shared between components, or if it does not directly produce DOM output, it belongs in a service.

No code yet — this lesson is conceptual. Answer:

  1. You are building a shopping cart. Where should the cart items array live — in the component that displays the cart, or in a service? Why?
  2. In CinemaVault, both NavBar and MovieCard need to know if a specific movie is in the watchlist. What problem would occur if each component maintained its own copy of the watchlist?
  3. Name one thing MovieService does that would be duplicated in every component if the service did not exist.
  • Services are TypeScript classes that hold shared logic and state outside of components.
  • They have no template — they produce no DOM output.
  • Components inject services and call their methods to access data or trigger actions.
  • CinemaVault uses MovieService for API calls, WatchlistService for watchlist state, and ToastService for notifications.
  • If logic needs to be shared between components, or if it does not produce view output, it belongs in a service.