📖 Scenario: You are building a NestJS service that optionally uses a logger service if it is provided. This is common when you want to add extra features without forcing them.
🎯 Goal: Create a NestJS service that optionally injects a LoggerService. If the logger is provided, the service uses it to log messages; if not, it works without errors.
📋 What You'll Learn
Create a LoggerService class with a log(message: string) method.
Create a MyService class that optionally injects LoggerService using @Optional().
In MyService, add a method doWork() that calls logger.log() only if the logger exists.
Set up a NestJS module that provides MyService and optionally provides LoggerService.
💡 Why This Matters
🌍 Real World
Optional providers are useful when you want to add features like logging, caching, or analytics only if they are configured, without forcing all parts of the app to depend on them.
💼 Career
Understanding optional providers helps you write flexible and maintainable NestJS applications that can adapt to different environments and requirements.
Progress0 / 4 steps
1
Create LoggerService class
Create a class called LoggerService with a method log(message: string) that does nothing inside.
NestJS
Hint
Define a class with a method named log that accepts a message string parameter.
2
Create MyService with optional LoggerService injection
Create a class called MyService with a constructor that optionally injects LoggerService using @Optional() and @Inject() decorators from @nestjs/common. Store it in a private readonly property called logger.
NestJS
Hint
Use @Optional() and @Inject(LoggerService) before the constructor parameter logger.
3
Add doWork method using optional logger
In the MyService class, add a method called doWork() that calls this.logger.log('Work done') only if this.logger exists.
NestJS
Hint
Check if this.logger is truthy before calling log.
4
Create module with optional LoggerService provider
Create a NestJS module class called AppModule that provides MyService. Also add LoggerService to the providers array but comment it out to simulate optional provision.
NestJS
Hint
Use @Module decorator with a providers array including MyService and a commented out LoggerService.
Practice
(1/5)
1. What is the main purpose of using @Optional() in a NestJS provider?
easy
A. To make a provider always required and throw error if missing
B. To mark a dependency as optional, so it may be undefined if not provided
C. To automatically create a new instance of the provider
D. To disable dependency injection for that provider
Solution
Step 1: Understand the role of @Optional()
@Optional() tells NestJS that the dependency might not be available and should not cause an error if missing.
Step 2: Compare with required providers
Without @Optional(), NestJS throws an error if the provider is not found. With @Optional(), it injects undefined instead.
Final Answer:
To mark a dependency as optional, so it may be undefined if not provided -> Option B
Quick Check:
@Optional() = marks provider optional [OK]
Hint: Optional means provider can be missing without error [OK]
Common Mistakes:
Thinking @Optional() makes provider required
Assuming @Optional() creates new instances
Believing @Optional() disables injection
2. Which of the following is the correct way to inject an optional provider in a NestJS constructor?
easy
A. constructor(@Optional() private readonly service: MyService) {}
B. constructor(private readonly service: MyService) {}
C. constructor(@InjectOptional() private readonly service: MyService) {}
D. constructor(@Optional private service: MyService) {}
Solution
Step 1: Recall the correct decorator syntax
The correct decorator to mark a provider optional is @Optional() with parentheses.
Step 2: Check each option
constructor(private readonly service: MyService) {} lacks @Optional, so provider is required. constructor(@InjectOptional() private readonly service: MyService) {} uses a non-existent decorator. constructor(@Optional private service: MyService) {} misses parentheses on @Optional.
Final Answer:
constructor(@Optional() private readonly service: MyService) {} -> Option A
C. Calling method on possibly undefined service without check
D. Incorrect use of @Optional() decorator without parentheses
Solution
Step 1: Check usage of optional provider
@Optional() means service can be undefined if not provided.
Step 2: Analyze method call in constructor
Calling this.service.doSomething() without checking if service exists can cause runtime error.
Final Answer:
Calling method on possibly undefined service without check -> Option C
Quick Check:
Always check optional provider before use [OK]
Hint: Check if optional provider exists before calling methods [OK]
Common Mistakes:
Calling methods on undefined optional providers
Assuming @Optional() means always injected
Ignoring runtime errors from missing checks
5. You want to inject an optional logging service in your NestJS component. If the logging service is missing, your component should still work without errors. Which approach correctly implements this behavior?
export class MyComponent {
constructor(@Optional() private readonly logger?: LoggerService) {}
logMessage(msg: string) {
// What should you do here?
}
}
hard
A. Call this.logger.log(msg) directly without checks
B. Throw an error if this.logger is undefined
C. Remove @Optional() to ensure logger is always injected
D. Use if (this.logger) this.logger.log(msg); to check before calling
Solution
Step 1: Understand optional injection with @Optional()
The logger may be undefined if not provided, so direct calls risk runtime errors.
Step 2: Implement safe usage in method
Check if this.logger exists before calling log() to avoid errors.
Final Answer:
Use if (this.logger) this.logger.log(msg); to check before calling -> Option D
Quick Check:
Check optional provider exists before use to avoid errors [OK]
Hint: Always check optional provider before method calls [OK]
Common Mistakes:
Calling methods without existence check
Throwing errors instead of handling missing provider
Removing @Optional() and causing injection errors
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.