Creating Services โ @Injectable Explained
Services are pure logic classes that Angular can inject into your components.
A service is a TypeScript class with a specific purpose โ data fetching, logging, state management, or business logic.
"Service = central kitchen โ components order, kitchen serves." Components are like restaurant tables (what you see), services are the kitchen (how things work).
Key characteristics:
- NOT a component โ no template, no DOM, no @Component decorator
- Pure logic โ API calls, data transformation, state management
- Injectable โ decorated with @Injectable so Angular can create and manage it
- Shared โ multiple components can use the same service instance
Why do we need services? Here are the main reasons:
- Share data between components โ No parent-child relationship needed. Two unrelated components can share the same service.
- Separate business logic from UI โ Components handle visual layout; services handle data operations.
- Easy to test โ Mock the service, test the component. Services themselves are easy to unit test.
- Single source of truth for API calls โ One service handles all data operations for a domain.
"Biryani recipe ek jagah likho โ 10 branches use karo, ek jagah change karo sab pe reflect." One recipe, multiple restaurants.
Creating a service is done with Angular CLI:
ng g s services/biryani
This generates:
import { Injectable, signal } from '@angular/core';\n\n@Injectable({\n providedIn: 'root', // Available everywhere!\n})\nexport class BiryaniService {\n // State management with signals\n private biryanis = signal([]);\n \n // Expose as readonly โ components can read but not modify directly\n readonly getAll = this.biryanis.asReadonly();\n \n getById(id: number): Biryani | undefined {\n return this.biryanis().find(b => b.id === id);\n }\n \n add(biryani: Biryani) {\n this.biryanis.update(list => [...list, biryani]);\n }\n \n remove(id: number) {\n this.biryanis.update(list => list.filter(b => b.id !== id));\n }\n}
"@Injectable = Angular ko batata hai ki ye service inject ho sakti hai."
providedIn: 'root' means one instance is created for the entire app and is available everywhere.
To use a service in a component, inject it:
import { Component, inject } from '@angular/core';\nimport { BiryaniService } from './services/biryani.service';\n\n@Component({\n selector: 'app-menu',\n standalone: true\n})\nexport class MenuComponent {\n // New way: field injection\n private biryaniService = inject(BiryaniService);\n \n // The service's readonly signal โ component can read and display\n biryanis = this.biryaniService.getAll;\n \n addNewBiryani() {\n this.biryaniService.add({\n id: Date.now(),\n name: 'Chicken Dum Biryani',\n price: 299\n });\n }\n}
"inject() = service ko bulao โ kaam karwao."
Multiple components that inject the same service get the same instance โ because of providedIn: 'root'.
Here's when to create a service vs keep logic in the component:
- API calls โ AuthService, BiryaniService, OrderService (always in service)
- State management โ CartService, UserService (shared state goes in service)
- Utility โ LoggerService, FormatService (reusable logic)
DON'T put DOM logic in a service (use directives).
DON'T put component-specific logic in a service (keep it in the component).
"Rule: agar 2+ components use karenge toh service banao, nahi toh component mein hi rakho."
Key Takeaways
- โ @Injectable makes a class a service โ Angular-managed, injectable anywhere.
- โ providedIn: 'root' creates a singleton available everywhere, tree-shakeable.
- โ Services handle logic โ API calls, shared state, utilities. Components handle UI.
- โ inject(ServiceName) in components accesses the service (new way).
- โ Create a service when 2+ components need the same data or logic.
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login