Bird
Raised Fist0
NestJSframework~10 mins

Custom providers in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Custom providers
Define provider token
↓
Create provider object with useClass/useValue/useFactory
↓
Register provider in module's providers array
↓
Inject provider using token in constructor
↓
Use provider instance in service/component
This flow shows how to create and use a custom provider in NestJS by defining a token, registering it, and injecting it where needed.
Execution Sample
NestJS
const MY_TOKEN = 'MY_TOKEN';

const myProvider = {
  provide: MY_TOKEN,
  useValue: { greet: () => 'Hello!' }
};
This code defines a custom provider with a token and a simple object value to be injected.
Execution Table
StepActionEvaluationResult
1Define token MY_TOKENMY_TOKEN is a string constantToken ready for provider
2Create provider object with provide and useValueuseValue is an object with greet methodProvider object created
3Register provider in module's providers arrayModule now knows MY_TOKEN providerProvider registered
4Inject provider in constructor using @Inject(MY_TOKEN)Injection token matches providerProvider instance available
5Call greet() method on injected providergreet() returns 'Hello!'Output: 'Hello!'
💡 Execution stops after provider is injected and used successfully
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
MY_TOKENundefined'MY_TOKEN''MY_TOKEN''MY_TOKEN''MY_TOKEN'
myProviderundefined{ provide: 'MY_TOKEN', useValue: { greet: [Function] } }Registered in moduleInjected instance availableInstance with greet method
InjectedInstanceundefinedundefinedundefined{ greet: [Function] }Used to call greet()
Key Moments - 3 Insights
Why do we need a token like MY_TOKEN instead of just using the class name?
The token uniquely identifies the provider, especially when using useValue or useFactory, so NestJS knows which provider to inject. See execution_table step 1 and 4.
What happens if the token in @Inject() does not match any registered provider?
NestJS throws an error because it cannot find a provider for that token. This is why matching tokens in steps 3 and 4 is crucial.
Can we use useClass instead of useValue in the provider object?
Yes, useClass lets NestJS instantiate a class for the provider. useValue provides a fixed object. Both are valid ways to create custom providers.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the result after step 5?
AOutput: 'Hello!'
BError because token is missing
CProvider instance is available but greet() is not called
DProvider object is undefined
💡 Hint
Check execution_table row with Step 5 for the output result
At which step is the provider registered in the module?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look for the step mentioning 'Register provider in module's providers array'
If we change useValue to useClass in the provider, what changes in variable_tracker?
AInjectedInstance becomes undefined
BMY_TOKEN value changes
CmyProvider becomes a class reference instead of an object
DNo changes at all
💡 Hint
Check variable_tracker row for myProvider and think about useClass vs useValue
Concept Snapshot
Custom providers in NestJS:
- Define a unique token (string or symbol)
- Create provider object with provide and useClass/useValue/useFactory
- Register provider in module's providers array
- Inject provider using @Inject(token) in constructor
- Use injected instance in your service/component
Full Transcript
Custom providers in NestJS let you define how dependencies are created and injected. First, you define a unique token to identify the provider. Then, you create a provider object specifying the token and how to create the value, using useClass for classes, useValue for fixed objects, or useFactory for functions. You register this provider in the module's providers array. When you want to use it, you inject it in a constructor using the @Inject decorator with the same token. This process allows you to customize dependency injection beyond just classes. The execution steps show defining the token, creating the provider, registering it, injecting it, and finally using the injected instance. Key points include matching tokens exactly and choosing the right provider type. This method helps you control what gets injected and how, making your code flexible and testable.

Practice

(1/5)
1. What is the main purpose of a custom provider in NestJS?
easy
A. To manage database connections automatically
B. To define routes for HTTP requests
C. To control how NestJS creates or finds a service or value
D. To handle user authentication and authorization

Solution

  1. Step 1: Understand the role of providers in NestJS

    Providers are responsible for creating and managing services or values that can be injected into other parts of the app.
  2. Step 2: Identify what custom providers do

    Custom providers let you control exactly how NestJS creates or finds these services or values, making your app more flexible.
  3. Final Answer:

    To control how NestJS creates or finds a service or value -> Option C
  4. Quick Check:

    Custom provider purpose = control creation/finding [OK]
Hint: Custom providers control service creation or retrieval [OK]
Common Mistakes:
  • Confusing providers with routing or middleware
  • Thinking providers manage database or auth directly
  • Assuming providers only register classes, not values or factories
2. Which of the following is the correct syntax to provide a custom value provider in a NestJS module?
easy
A. { provide: 'API_URL', useValue: 'https://api.example.com' }
B. { provide: 'API_URL', useClass: 'https://api.example.com' }
C. { provide: 'API_URL', useFactory: 'https://api.example.com' }
D. { provide: 'API_URL', useExisting: 'https://api.example.com' }

Solution

  1. Step 1: Recall the syntax for value providers

    Value providers use the useValue key to assign a fixed value to a token.
  2. Step 2: Check each option's correctness

    { provide: 'API_URL', useValue: 'https://api.example.com' } correctly uses useValue with a string value. Other options misuse useClass, useFactory, or useExisting which expect different types.
  3. Final Answer:

    { provide: 'API_URL', useValue: 'https://api.example.com' } -> Option A
  4. Quick Check:

    Value provider uses useValue = { provide: 'API_URL', useValue: 'https://api.example.com' } [OK]
Hint: Value providers always use 'useValue' key [OK]
Common Mistakes:
  • Using useClass or useFactory for fixed values
  • Confusing useExisting with useValue
  • Putting string directly without useValue
3. Given the following provider configuration in a NestJS module:
{ provide: 'RANDOM_NUMBER', useFactory: () => Math.floor(Math.random() * 10) }
What will be the output if you inject 'RANDOM_NUMBER' twice in the same request?
medium
A. The same random number both times
B. Always zero because Math.random() is called once
C. An error because useFactory cannot be used this way
D. Two different random numbers between 0 and 9

Solution

  1. Step 1: Understand provider scope and factory behavior

    By default, NestJS providers are singletons per application context, so the factory runs once and the result is reused.
  2. Step 2: Analyze injection behavior

    Injecting 'RANDOM_NUMBER' twice in the same request returns the same value because the factory was called once at provider creation.
  3. Final Answer:

    The same random number both times -> Option A
  4. Quick Check:

    Singleton factory = same value injected [OK]
Hint: Default providers are singletons; factory runs once [OK]
Common Mistakes:
  • Assuming factory runs on every injection
  • Thinking useFactory causes errors without async
  • Believing random number changes per injection
4. Consider this provider configuration:
{ provide: 'CONFIG', useFactory: () => ({ port: 3000 }) }
If you want to inject this provider but get an error "Nest can't resolve dependencies", what is the most likely cause?
medium
A. The token 'CONFIG' must be a class, not a string
B. The useFactory function must be async
C. You cannot use useFactory with object literals
D. The provider is missing from the module's providers array

Solution

  1. Step 1: Check provider registration

    For NestJS to inject a provider, it must be registered in the module's providers array.
  2. Step 2: Evaluate other options

    useFactory can be sync or async, tokens can be strings, and useFactory can return objects. The error usually means the provider is not registered.
  3. Final Answer:

    The provider is missing from the module's providers array -> Option D
  4. Quick Check:

    Missing provider registration = injection error [OK]
Hint: Always register providers in module's providers array [OK]
Common Mistakes:
  • Assuming useFactory must be async
  • Thinking tokens must be classes only
  • Believing useFactory can't return objects
5. You want to create a custom provider that returns different database connection strings based on environment variables. Which approach correctly implements this using a factory provider in NestJS?
hard
A. { provide: 'DB_CONNECTION', useValue: process.env.NODE_ENV === 'prod' ? 'prod-db' : 'dev-db' }
B. { provide: 'DB_CONNECTION', useFactory: () => process.env.NODE_ENV === 'prod' ? 'prod-db' : 'dev-db' }
C. { provide: 'DB_CONNECTION', useClass: process.env.NODE_ENV === 'prod' ? ProdDbService : DevDbService }
D. { provide: 'DB_CONNECTION', useExisting: process.env.NODE_ENV === 'prod' ? 'ProdDbService' : 'DevDbService' }

Solution

  1. Step 1: Understand dynamic value creation

    To choose a value based on environment variables at runtime, a factory provider is ideal because it runs code to decide the value.
  2. Step 2: Evaluate each option

    { provide: 'DB_CONNECTION', useFactory: () => process.env.NODE_ENV === 'prod' ? 'prod-db' : 'dev-db' } uses useFactory with a function that returns the correct string based on process.env.NODE_ENV. { provide: 'DB_CONNECTION', useValue: process.env.NODE_ENV === 'prod' ? 'prod-db' : 'dev-db' } uses useValue which is static at module load time. Options C and D misuse useClass and useExisting with strings or conditions incorrectly.
  3. Final Answer:

    { provide: 'DB_CONNECTION', useFactory: () => process.env.NODE_ENV === 'prod' ? 'prod-db' : 'dev-db' } -> Option B
  4. Quick Check:

    Dynamic values need useFactory with runtime logic [OK]
Hint: Use useFactory for runtime-dependent values [OK]
Common Mistakes:
  • Using useValue for dynamic environment-based values
  • Misusing useClass or useExisting with strings
  • Expecting useFactory to be static
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard