ViewProviders are similar to Providers except that the dependencies that you define are visible only to its view children. They are not visible to the Content children.
ViewProviders Example
Look at the example app at stackblitz
The app has RandomService
, which generates a random number when initialized.
random-service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import { Injectable } from "@angular/core"; @Injectable({ providedIn: "root" }) export class RandomService { private _randomNo = 0; constructor() { console.log("RandomService Constructed"); this._randomNo = Math.floor(Math.random() * 1000); } get RandomNo() { return this._randomNo; } } |
ChildComponent
displays the random no from the RandomService
.
It also has ng-content, where the parent can inject content. The Parent component is going to inject the GrandChildComponent
here.
ChildComponent
also displays the GrandChildComponent
as View
child.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { Component, SkipSelf, Self, Optional, Host } from '@angular/core'; import { RandomService } from './random-service'; @Component({ selector: 'my-child', providers: [], viewProviders: [], template: ` <div class="box"> <p>ChildComponent => {{ randomNo }}</p> <ng-content> </ng-content> <strong>View Child</strong> <my-grandChild></my-grandChild> </div> ` }) export class ChildComponent { randomNo; constructor(private randomService: RandomService) { this.randomNo = randomService.RandomNo; } } |
GrandChildComponent
just displays the random no from the RandomService
. We use @Optional()
decorator ensures no error is thrown if the dependency is not found.
grand-child.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import { Component, SkipSelf, Self, Optional, Host } from "@angular/core"; import { RandomService } from "./random-service"; @Component({ selector: "my-grandChild", template: ` <div class="box"> GrandChildComponent => {{ randomNo }} </div> `, providers: [], viewProviders: [], }) export class GrandChildComponent { randomNo; constructor(@Optional() private randomService: RandomService) { this.randomNo = randomService?.RandomNo; } } |
In the AppComponent
, we display the ChildComponent
. We also project the GrandChildComponent
inside the ChildComponent
using projected content.
app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import { Component, VERSION } from '@angular/core'; import { RandomService } from './random-service'; @Component({ selector: 'my-app', providers: [], viewProviders: [], template: ` <div class="box"> <div class="box"> <p>AppComponent => {{ randomNo }}</p> <my-child> <strong>Projected Content</strong> <my-grandChild></my-grandChild> </my-child> </div> ` }) export class AppComponent { randomNo; constructor(private randomService: RandomService) { this.randomNo = randomService.RandomNo; } } |
Run the app and you will see all the components receive the same value for the random no. Because the RandomService is provided from the root module injector.
Also, note that ChildComponent displays the GrandChildComponent
twice. Once as a Content Child (Projected Content) and also a View Child.
Add the RandomService
to the Providers array of the ChildComponent
. As you can see from the image below, ChildComponent
and all its children (content children and view children) gets the instance of the RandomService
provided by the ChildComponent
.

Now, move the RandomService from Providers to ViewProviders. As you can see in the image below View Child still get the RandomService from ChildComponent, but the Projected Content does not. Projected Content gets the service from the Root Module.

The providers
allow all children to use the services. While the viewProviders
limit it to children other than projected content.
Use case for ViewProviders
This is useful when you develop libraries.
For Example, you have made some-great-comp
, which user will be using it to project their user-component
into it.
1 2 3 4 5 | <some-great-comp> <user-component></user-component> </some-great-comp> |
Here you do not want services that you used in your some-great-comp
interfere with the user-component
. Hence you provide your services in the ViewProviders
.