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.
The problem services solve
Section titled “The problem services solve”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:
@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.
Services in CinemaVault
Section titled “Services in CinemaVault”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.
Services vs. components
Section titled “Services vs. components”| Component | Service |
|---|---|
| Manages a piece of the view | Manages logic or state |
| Has a template | Has no template |
| Created and destroyed with the DOM | Typically lives as long as the app |
| Communicates via inputs/outputs | Communicates 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.
Exercise
Section titled “Exercise”No code yet — this lesson is conceptual. Answer:
- 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?
- In CinemaVault, both
NavBarandMovieCardneed to know if a specific movie is in the watchlist. What problem would occur if each component maintained its own copy of the watchlist? - Name one thing
MovieServicedoes 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
MovieServicefor API calls,WatchlistServicefor watchlist state, andToastServicefor notifications. - If logic needs to be shared between components, or if it does not produce view output, it belongs in a service.