The @Injectable decorator tells Angular that a class can be used to provide data or logic to other parts of the app. The providedIn option helps Angular know where to create and share this service.
@Injectable decorator and providedIn in Angular
@Injectable({
providedIn: 'root' | 'platform' | 'any' | SomeModule
})
export class MyService {
// service code here
}providedIn: 'root' means the service is available everywhere in the app.
You can also specify a module to limit the service scope or use 'any' for multiple instances.
DataService available throughout the whole app.@Injectable({
providedIn: 'root'
})
export class DataService {
// shared data service
}LoggerService instance.@Injectable({
providedIn: 'any'
})
export class LoggerService {
// creates a new instance in each lazy loaded module
}SomeModule is loaded.@Injectable({
providedIn: SomeModule
})
export class FeatureService {
// only available in SomeModule
}providedIn, you must add this service to a module's providers array.@Injectable() export class OldService { // no providedIn, must add to module providers manually }
This example shows a simple service GreetingService that is provided in the root injector. The WelcomeComponent uses this service to get a greeting message and display it.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class GreetingService { getGreeting(name: string): string { return `Hello, ${name}!`; } } // Usage in a component import { Component } from '@angular/core'; import { GreetingService } from './greeting.service'; @Component({ selector: 'app-welcome', template: `<h1>{{ greeting }}</h1>` }) export class WelcomeComponent { greeting = ''; constructor(private greetingService: GreetingService) { this.greeting = this.greetingService.getGreeting('Friend'); } }
Using providedIn helps Angular tree-shake unused services, making your app smaller.
Always prefer providedIn: 'root' for app-wide singleton services.
If you forget providedIn and don't add the service to providers, Angular will throw an error.
@Injectable marks a class as a service that Angular can inject.
providedIn controls where and how Angular creates the service instance.
Using providedIn simplifies service registration and improves app performance.
Practice
@Injectable decorator in Angular?Solution
Step 1: Understand the role of
The@Injectable@Injectabledecorator tells Angular that the class can be used as a service and injected into other classes.Step 2: Differentiate from other decorators
Other decorators like@Componentor@NgModuleserve different purposes, not marking services.Final Answer:
To mark a class as a service that Angular can inject -> Option AQuick Check:
@Injectable= marks service [OK]
@Injectable means service ready for injection [OK]- Confusing
@Injectablewith@Component - Thinking it registers modules
- Assuming it creates directives
@Injectable?Solution
Step 1: Recall the correct property name
The correct property to specify where the service is provided isprovidedIn, notprovideInor others.Step 2: Confirm the value for root-level provision
Using'root'as the value means the service is available app-wide as a singleton.Final Answer:
@Injectable({ providedIn: 'root' }) -> Option BQuick Check:
providedIn: 'root'is correct syntax [OK]
providedIn with value 'root' [OK]- Misspelling
providedInasprovideIn - Using
providedAtorprovideAt - Omitting quotes around 'root'
@Injectable({ providedIn: 'root' })
export class DataService {
constructor() { console.log('Service created'); }
}Solution
Step 1: Understand
This means Angular will create one singleton instance of the service for the whole app.providedIn: 'root'Step 2: Check service creation behavior
The constructor logs 'Service created' only once when the singleton is created, not on every injection.Final Answer:
Angular creates a single instance shared across the app -> Option DQuick Check:
providedIn: 'root'means singleton service [OK]
- Thinking a new instance is created on each injection
- Assuming an error due to wrong providedIn
- Believing manual provider registration is needed
@Injectable({
providedIn: root
})
export class LoggerService {}Solution
Step 1: Check syntax of providedIn value
The value 'root' must be a string, so it needs quotes: 'root'. Without quotes, it's treated as an undefined variable.Step 2: Verify other parts
The decorator name@Injectableis correct, constructor is optional, andprovidedInis valid here.Final Answer:
Missing quotes around 'root' in providedIn -> Option CQuick Check:
String values need quotes inprovidedIn[OK]
- Omitting quotes around 'root'
- Confusing decorator names
- Thinking constructor is mandatory
@Injectable and providedIn to achieve this?Solution
Step 1: Understand providedIn options
UsingprovidedIn: 'root'makes the service app-wide singleton, so not limited to a feature module.Step 2: Provide service only in feature module
UsingprovidedIn: FeatureModulewhere FeatureModule is the NgModule class is possible but not officially recommended or supported in all Angular versions. The standard way is to omitprovidedInand add the service to the feature module'sprovidersarray.Step 3: Evaluate other options
providedIn: 'any'creates a new instance in each injector but does not restrict to a single module. Importing withprovidedIn: 'root'makes it app-wide.Final Answer:
Use@Injectable()without providedIn and add the service to the feature module's providers array -> Option AQuick Check:
OmittingprovidedInand adding to providers array scopes service to module [OK]
- Using providedIn: 'root' for feature-only service
- Using providedIn: FeatureModule which is not standard
- Misunderstanding providedIn: 'any' scope
Ready to prove it?
Pass the test and this pattern moves unknown
