📖 Scenario: You are building a simple NestJS service that calculates discounts for products in an online store.To keep your code clean and testable, you will use constructor injection to provide the discount calculation logic to your service.
🎯 Goal: Create a NestJS service that uses constructor injection to receive a discount provider and applies it to product prices.
📋 What You'll Learn
Create a discount provider class with a method to calculate discount
Create a service class that receives the discount provider via constructor injection
Use the injected discount provider inside the service method to calculate discounted price
Export the service class properly for use in a NestJS module
💡 Why This Matters
🌍 Real World
Constructor injection is a common pattern in NestJS to manage dependencies like services, repositories, and providers cleanly.
💼 Career
Understanding constructor injection is essential for building scalable and maintainable backend applications with NestJS, a popular Node.js framework.
Progress0 / 4 steps
1
Create the DiscountProvider class
Create a class called DiscountProvider with a method getDiscount() that returns the number 0.1 (representing a 10% discount).
NestJS
Hint
Think of DiscountProvider as a helper that tells how much discount to apply.
2
Create the PricingService class with constructor injection
Create a class called PricingService that has a constructor with a parameter called discountProvider of type DiscountProvider. Store this parameter in a private readonly property.
NestJS
Hint
Use private readonly in the constructor parameter to automatically create and assign the property.
3
Add a method to calculate discounted price
Inside PricingService, add a method called calculatePrice that takes a price number parameter and returns the price after subtracting the discount. Use this.discountProvider.getDiscount() to get the discount rate.
NestJS
Hint
Calculate the discounted price by subtracting price * discount from the original price.
4
Export the PricingService class
Make sure the PricingService class is exported so it can be used in other parts of the NestJS application.
NestJS
Hint
Use export { PricingService }; to export the class explicitly.
Practice
(1/5)
1. What is the main purpose of constructor injection in NestJS?
easy
A. To provide required services to a class when it is created
B. To manually create instances of services inside methods
C. To define routes for HTTP requests
D. To write database queries inside the constructor
Solution
Step 1: Understand constructor injection concept
Constructor injection is used to pass dependencies (services) into a class automatically when it is created.
Step 2: Identify the purpose in NestJS context
In NestJS, constructor injection helps keep code clean by providing needed services without manual instantiation.
Final Answer:
To provide required services to a class when it is created -> Option A
Quick Check:
Constructor injection = provide services automatically [OK]
Hint: Constructor injection means passing services via constructor [OK]
Common Mistakes:
Thinking constructor injection creates routes
Manually creating service instances inside methods
Confusing injection with database queries
2. Which of the following is the correct syntax for constructor injection of a service named UsersService in a NestJS class?
easy
A. constructor(private readonly usersService: UsersService) {}
B. constructor(usersService: UsersService) {}
C. constructor(private usersService) {}
D. constructor(public readonly usersService) {}
Solution
Step 1: Check for correct access modifier and typing
In NestJS, constructor injection requires private readonly with the service type for proper injection and immutability.
Step 2: Compare options
constructor(private readonly usersService: UsersService) {} (A) is correct. B misses access modifier, C misses type, D misses type annotation.
Final Answer:
constructor(private readonly usersService: UsersService) {} -> Option A
Quick Check:
Use private readonly with type for injection [OK]
Hint: Use 'private readonly serviceName: ServiceType' in constructor [OK]
Common Mistakes:
Omitting access modifier like private or public
Not specifying the service type
Using public readonly without specifying the service type
3. Given the following code, what will be the output when appController.getHello() is called?
The AppController receives HelloService via constructor injection and stores it as helloService.
Step 2: Trace method call
Calling getHello() calls helloService.getMessage() which returns 'Hello, NestJS!'.
Final Answer:
'Hello, NestJS!' -> Option C
Quick Check:
Injected service method returns 'Hello, NestJS!' [OK]
Hint: Injected service methods return expected values [OK]
Common Mistakes:
Assuming service is undefined without injection
Confusing method return values
Expecting default or unrelated strings
4. Identify the error in the following NestJS service injection code:
@Injectable()
class CatsService {}
@Controller('cats')
class CatsController {
constructor(catsService: CatsService) {}
findAll() {
return 'All cats';
}
}
medium
A. CatsService is not decorated with @Injectable()
B. Missing access modifier (private/public) in constructor parameter
C. Controller decorator is missing path
D. findAll method should be async
Solution
Step 1: Check constructor injection syntax
The constructor parameter catsService: CatsService lacks an access modifier like private or public, so it won't be assigned as a class property.
Step 2: Verify other parts
@Injectable() is present on service, @Controller('cats') has path, and findAll can be sync. So no other errors.
Final Answer:
Missing access modifier (private/public) in constructor parameter -> Option B
Quick Check:
Constructor injection needs access modifier [OK]
Hint: Always add private/public to constructor params for injection [OK]
Common Mistakes:
Omitting private/public in constructor injection
Thinking @Injectable is missing when it is present
Assuming controller path is mandatory for injection
5. You want to inject two services, AuthService and UsersService, into a NestJS controller. Which constructor correctly injects both services following best practices?
hard
A. constructor(public authService: AuthService, public usersService: UsersService) {}
B. constructor(authService: AuthService, usersService: UsersService) {}
C. constructor(private authService: AuthService, usersService: UsersService) {}
D. constructor(private readonly authService: AuthService, private readonly usersService: UsersService) {}
Solution
Step 1: Check for access modifiers and readonly usage
Best practice is to use private readonly for injected services to keep them immutable and private.
Step 2: Verify both services are injected with correct syntax
constructor(private readonly authService: AuthService, private readonly usersService: UsersService) {} injects both services with private readonly, while others miss modifiers or use public.