Skip to content

Services

A service is a plain class marked @Injectable() used to hold logic and state that shouldn’t live inside a component β€” API calls, shared data, business logic. Services are the standard way to share functionality across multiple components without duplicating code or tightly coupling components to each other, and Angular’s dependency injection system supplies them automatically.

@Injectable({ providedIn: 'root' }) // singleton, shared across the whole app
export class CartService {
private items: Product[] = [];
addItem(product: Product) {
this.items.push(product);
}
getTotal(): number {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
@Component({ selector: 'app-product', template: `...` })
export class ProductComponent {
private cart = inject(CartService);
addToCart(product: Product) {
this.cart.addItem(product); // same service instance used by every component
}
}
@Component({ selector: 'app-cart-summary', template: `Total: {{ total }}` })
export class CartSummaryComponent {
private cart = inject(CartService);
total = this.cart.getTotal(); // sees items added from ANY component, since it's the same instance
}

Putting business logic and API calls directly inside a component instead of extracting them into a service β€” this makes the logic impossible to reuse elsewhere and much harder to unit test, since it’s now entangled with the component’s template and change detection.

// Logic trapped inside the component -- can't be reused or tested independently
@Component({ selector: 'app-checkout' })
export class CheckoutComponent {
total = 0;
calculateTotal(items: Product[]) {
this.total = items.reduce((sum, i) => sum + i.price * 1.08, 0); // tax logic buried here
}
}
// Better: extract to a service, reusable and independently testable
@Injectable({ providedIn: 'root' })
export class PricingService {
calculateTotal(items: Product[]): number {
return items.reduce((sum, i) => sum + i.price * 1.08, 0);
}
}
  1. What decorator marks a class as an injectable service?

    Answer@Injectable().
  2. Why extract logic into a service instead of keeping it in a component?

    AnswerServices can be shared across multiple components without duplication, and are much easier to unit test in isolation, since they're not entangled with a component's template or lifecycle.
  3. If two components both inject the same providedIn: 'root' service, do they get separate instances?

    AnswerNo β€” providedIn: 'root' makes it a singleton; both components share the exact same instance, so state changes made through one are visible to the other.