0
0
Angularframework~20 mins

Multi-provider pattern in Angular - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Multi-provider Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What will be the output of this Angular component using multi-provider pattern?

Consider this Angular service and component setup using multi-provider pattern. What will the component display?

Angular
import { Component, Inject, InjectionToken } from '@angular/core';

export interface Logger {
  log(message: string): string;
}

export const LOGGER_TOKEN = new InjectionToken<Logger>('LOGGER_TOKEN');

export class ConsoleLogger implements Logger {
  log(message: string): string {
    return `ConsoleLogger: ${message}`;
  }
}

export class FileLogger implements Logger {
  log(message: string): string {
    return `FileLogger: ${message}`;
  }
}

@Component({
  selector: 'app-log-display',
  template: `<div>{{logs.join(' | ')}}</div>`,
  providers: [
    { provide: LOGGER_TOKEN, useClass: ConsoleLogger, multi: true },
    { provide: LOGGER_TOKEN, useClass: FileLogger, multi: true }
  ]
})
export class LogDisplayComponent {
  logs: string[] = [];
  constructor(@Inject(LOGGER_TOKEN) private loggers: Logger[]) {
    this.logs = this.loggers.map(logger => logger.log('Test'));
  }
}
AConsoleLogger: Test
BConsoleLogger: Test | FileLogger: Test
CFileLogger: Test
DError: No provider for LOGGER_TOKEN
Attempts:
2 left
💡 Hint

Remember that multi: true allows multiple providers to be injected as an array.

📝 Syntax
intermediate
1:30remaining
Which option correctly registers multiple providers for the same token in Angular?

Choose the correct syntax to register two classes as multi-providers for the same injection token.

Angular
import { InjectionToken } from '@angular/core';

export const MY_TOKEN = new InjectionToken<string>('MY_TOKEN');

export class ServiceA {}
export class ServiceB {}
A{ provide: MY_TOKEN, useClass: ServiceA, multi: true }, { provide: MY_TOKEN, useClass: ServiceB, multi: true }
B{ provide: MY_TOKEN, useClass: ServiceA }, { provide: MY_TOKEN, useClass: ServiceB }
C{ provide: MY_TOKEN, useClass: ServiceA, multi: false }, { provide: MY_TOKEN, useClass: ServiceB, multi: false }
D{ provide: MY_TOKEN, useClass: ServiceA, multi: true }, { provide: MY_TOKEN, useClass: ServiceB }
Attempts:
2 left
💡 Hint

Multi-providers require multi: true on all provider entries.

🔧 Debug
advanced
2:30remaining
Why does this Angular multi-provider injection cause a runtime error?

Given this provider setup, the app crashes with 'NullInjectorError: No provider for LOGGER_TOKEN!'. What is the cause?

Angular
import { Component, Inject, InjectionToken } from '@angular/core';

export interface Logger {
  log(message: string): string;
}

export class ConsoleLogger implements Logger {
  log(message: string): string {
    return `ConsoleLogger: ${message}`;
  }
}

export const LOGGER_TOKEN = new InjectionToken<Logger>('LOGGER_TOKEN');

@Component({
  selector: 'app-root',
  template: `<app-log-display></app-log-display>`,
  providers: [
    { provide: LOGGER_TOKEN, useClass: ConsoleLogger, multi: true }
  ]
})
export class AppComponent {}

@Component({
  selector: 'app-log-display',
  template: `<div>{{logs}}</div>`
})
export class LogDisplayComponent {
  logs: string = '';
  constructor(@Inject(LOGGER_TOKEN) private loggers: Logger[]) {
    this.logs = loggers.map(l => l.log('Hi')).join(', ');
  }
}
ALOGGER_TOKEN is not provided in a shared or parent injector accessible to LogDisplayComponent
BLogDisplayComponent is not declared in the same module as AppComponent
CLogDisplayComponent does not have providers array with LOGGER_TOKEN multi-provider
DMulti-provider tokens cannot be injected as arrays
Attempts:
2 left
💡 Hint

Consider Angular's hierarchical injectors and where providers are declared.

🧠 Conceptual
advanced
1:30remaining
What is the main benefit of using Angular's multi-provider pattern?

Why would a developer choose to use the multi-provider pattern in Angular dependency injection?

ATo improve performance by caching a single instance of a service
BTo override existing providers with a new single provider for the token
CTo allow multiple classes to be injected as an array for the same token, enabling extensible service collections
DTo automatically lazy load services only when needed
Attempts:
2 left
💡 Hint

Think about scenarios where you want many implementations under one token.

state_output
expert
3:00remaining
What is the value of 'logs' after this Angular component runs with multi-provider pattern?

Analyze the following Angular component using multi-provider pattern. What is the final value of the logs array?

Angular
import { Component, Inject, InjectionToken } from '@angular/core';

export interface Logger {
  log(message: string): string;
}

export const LOGGER_TOKEN = new InjectionToken<Logger>('LOGGER_TOKEN');

export class LoggerA implements Logger {
  log(message: string): string {
    return `A:${message}`;
  }
}

export class LoggerB implements Logger {
  log(message: string): string {
    return `B:${message}`;
  }
}

@Component({
  selector: 'app-root',
  template: `<div>{{logs.join(',')}}</div>`,
  providers: [
    { provide: LOGGER_TOKEN, useClass: LoggerA, multi: true },
    { provide: LOGGER_TOKEN, useClass: LoggerB, multi: true },
    { provide: LOGGER_TOKEN, useClass: LoggerA, multi: true }
  ]
})
export class AppComponent {
  logs: string[] = [];
  constructor(@Inject(LOGGER_TOKEN) private loggers: Logger[]) {
    this.logs = this.loggers.map(l => l.log('hello'));
  }
}
A[]
B["A:hello", "B:hello"]
C["B:hello", "A:hello", "B:hello"]
D["A:hello", "B:hello", "A:hello"]
Attempts:
2 left
💡 Hint

Multi-providers accumulate all providers in order of declaration.