Services
Services
Section titled βServicesβWhat it means
Section titled βWhat it meansβ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.
Examples
Section titled βExamplesβ@Injectable({ providedIn: 'root' }) // singleton, shared across the whole appexport 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}Common mistake
Section titled βCommon mistakeβ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); }}Quick practice
Section titled βQuick practiceβ-
What decorator marks a class as an injectable service?
Answer
@Injectable(). -
Why extract logic into a service instead of keeping it in a component?
Answer
Services 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. -
If two components both inject the same
providedIn: 'root'service, do they get separate instances?Answer
No βprovidedIn: 'root'makes it a singleton; both components share the exact same instance, so state changes made through one are visible to the other.