Bird
Raised Fist0
Angularframework~10 mins

How dependency injection works in Angular - Visual Walkthrough

Choose your learning style10 modes available
Concept Flow - How dependency injection works in Angular
Component or Service needs a dependency
↓
Angular checks the injector tree
↓
Find provider for the dependency
↓
Create instance if not created
↓
Inject instance into the requester
↓
Component/Service uses the dependency
Angular looks for the requested dependency in its injector tree, creates it if needed, and provides it to the component or service that asked for it.
Execution Sample
Angular
import { Injectable, inject } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class LoggerService {
  log(msg: string) { console.log(msg); }
}

export class AppComponent {
  private logger = inject(LoggerService);
  constructor() { this.logger.log('App started'); }
}
This code shows Angular injecting LoggerService into AppComponent using the inject() function.
Execution Table
StepActionInjector StateDependency FoundInstance CreatedInjected Into
1AppComponent requests LoggerServiceEmptyNoNoNo
2Angular checks root injectorEmptyYesNoNo
3LoggerService instance createdLoggerService instance createdYesYesNo
4LoggerService instance injected into AppComponentLoggerService instance createdYesYesAppComponent
5AppComponent calls logger.log()LoggerService instance createdYesYesAppComponent
💡 Dependency injected and used; execution stops after AppComponent construction.
Variable Tracker
VariableStartAfter Step 3After Step 4Final
LoggerService instanceundefinedcreatedcreatedcreated
AppComponent.loggerundefinedundefinedLoggerService instanceLoggerService instance
Key Moments - 3 Insights
Why does Angular create only one instance of LoggerService?
Because LoggerService is provided in 'root', Angular creates a singleton instance in the root injector as shown in execution_table step 3.
What happens if the dependency is not found in the injector?
Angular throws an error because it cannot provide the requested dependency, but in this example, the dependency is found at step 2.
How does Angular know where to inject the dependency?
Angular uses the inject() function or constructor parameters to know where to inject, demonstrated in step 4 where the instance is injected into AppComponent.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step is the LoggerService instance created?
AStep 2
BStep 3
CStep 1
DStep 4
💡 Hint
Check the 'Instance Created' column in the execution_table.
According to the variable tracker, when does AppComponent.logger get assigned the LoggerService instance?
AAfter Step 4
BAfter Step 3
CAfter Step 2
DAt Start
💡 Hint
Look at the 'AppComponent.logger' row in variable_tracker after Step 4.
If LoggerService was not provided in 'root', what would happen during injection?
AAngular would create a new instance anyway
BAngular would inject null
CAngular would throw an error at step 2
DAngular would skip injection
💡 Hint
Refer to key_moments about what happens if dependency is not found.
Concept Snapshot
Angular Dependency Injection (DI):
- Components or services request dependencies.
- Angular checks injector tree for providers.
- Creates singleton instances if needed.
- Injects instances where requested.
- Use @Injectable and inject() for DI.
- Root injector provides app-wide singletons.
Full Transcript
Dependency injection in Angular works by components or services asking for dependencies. Angular looks into its injector tree to find a provider for the requested dependency. If the provider exists and no instance is created yet, Angular creates one. Then Angular injects this instance into the requester. For example, a LoggerService marked with @Injectable({providedIn: 'root'}) is created once in the root injector. When AppComponent uses inject(LoggerService), Angular provides the same LoggerService instance. This process ensures efficient reuse and easy testing. If Angular cannot find a provider, it throws an error. This flow is shown step-by-step in the execution table and variable tracker.

Practice

(1/5)
1. What is the main purpose of dependency injection in Angular?
easy
A. To write all code inside a single file
B. To manually create instances of services inside components
C. To provide components with the services they need automatically
D. To prevent components from using any services

Solution

  1. Step 1: Understand dependency injection concept

    Dependency injection automatically provides required services to components without manual creation.
  2. Step 2: Compare options with this concept

    Only To provide components with the services they need automatically describes automatic provision of services, which is the core of dependency injection.
  3. Final Answer:

    To provide components with the services they need automatically -> Option C
  4. Quick Check:

    Dependency injection = automatic service provision [OK]
Hint: Dependency injection means Angular gives services automatically [OK]
Common Mistakes:
  • Thinking you must create service instances manually
  • Believing dependency injection restricts service use
  • Confusing dependency injection with code organization
2. Which decorator makes a class injectable in Angular?
easy
A. @Component
B. @Input
C. @NgModule
D. @Injectable

Solution

  1. Step 1: Identify Angular decorators for injection

    The decorator @Injectable marks a class as available for dependency injection.
  2. Step 2: Eliminate other decorators

    @Component is for components, @NgModule for modules, and @Input for input properties, none make a class injectable.
  3. Final Answer:

    @Injectable -> Option D
  4. Quick Check:

    @Injectable = makes class injectable [OK]
Hint: Use @Injectable to mark services for injection [OK]
Common Mistakes:
  • Confusing @Component with @Injectable
  • Using @NgModule to make services injectable
  • Forgetting to add @Injectable to services
3. Given this Angular service and component code, what will be logged?
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class LoggerService {
  log(message: string) {
    console.log('Log:', message);
  }
}

import { Component } from '@angular/core';
import { LoggerService } from './logger.service';

@Component({ selector: 'app-root', template: '' })
export class AppComponent {
  constructor(private logger: LoggerService) {
    this.logger.log('Hello');
  }
}
medium
A. Log: Hello
B. Error: LoggerService not found
C. No output
D. Log: undefined

Solution

  1. Step 1: Understand service injection in constructor

    The LoggerService is injected into AppComponent via constructor and used to log a message.
  2. Step 2: Analyze the log call

    The log method prints 'Log:' plus the message 'Hello', so console shows 'Log: Hello'.
  3. Final Answer:

    Log: Hello -> Option A
  4. Quick Check:

    Injected service logs message correctly [OK]
Hint: Injected services work via constructor parameters [OK]
Common Mistakes:
  • Expecting error if service is providedIn root
  • Thinking log method won't run without template
  • Confusing console output with return value
4. What is wrong with this Angular service injection code?
import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  getData() { return [1, 2, 3]; }
}

import { Component } from '@angular/core';

@Component({ selector: 'app-data', template: '' })
export class DataComponent {
  constructor(private dataService: DataService) {}
}
medium
A. DataComponent constructor should not have parameters
B. DataService is not provided in any injector
C. DataService class is missing @Component decorator
D. getData method must be static

Solution

  1. Step 1: Check service provider configuration

    The service has @Injectable() but no providedIn or provider registration, so Angular doesn't know where to provide it.
  2. Step 2: Understand injection failure cause

    Without being provided, Angular throws an error when injecting DataService into DataComponent.
  3. Final Answer:

    DataService is not provided in any injector -> Option B
  4. Quick Check:

    Missing provider causes injection error [OK]
Hint: Always provide services via providedIn or providers array [OK]
Common Mistakes:
  • Assuming @Injectable alone provides the service
  • Adding @Component to services incorrectly
  • Thinking constructor parameters are optional for injection
5. You want to inject two different services of the same class but with different configurations in Angular. Which approach correctly achieves this?
hard
A. Use Angular injection tokens to provide different configurations and inject by token
B. Create two different classes extending the service and inject each separately
C. Use @Injectable({ providedIn: 'root' }) on the class and inject twice in constructor
D. Inject the service once and manually change its configuration before each use

Solution

  1. Step 1: Understand multiple instances need

    Injecting the same class twice with different configs requires distinguishing them in Angular's injector.
  2. Step 2: Use injection tokens for different configs

    Angular injection tokens allow providing multiple versions of the same class with different configurations and injecting them separately.
  3. Step 3: Evaluate other options

    Use @Injectable({ providedIn: 'root' }) on the class and inject twice in constructor injects the same instance twice, B duplicates classes unnecessarily, D is error-prone and not recommended.
  4. Final Answer:

    Use Angular injection tokens to provide different configurations and inject by token -> Option A
  5. Quick Check:

    Injection tokens enable multiple configured instances [OK]
Hint: Use injection tokens for multiple differently configured services [OK]
Common Mistakes:
  • Injecting same service twice without tokens
  • Creating duplicate service classes unnecessarily
  • Changing service config manually at runtime
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