Exploring ViewChild Selectors
Hassam Ali
Posted on July 27, 2020
ViewChild
ViewChild
decorator is most commonly used to access the Child Component's instance and template. This is one the most common use cases. In this article we will be exploring several lesser known use cases.
ViewChild
Selectors
The ViewChild
has following selectors
- Any class with the @Component or @Directive decorator
- A template reference variable as a string (e.g. query with @ViewChild('cmp'))
- Any provider defined in the child component tree of the current component (e.g. @ViewChild(SomeService) someService: SomeService)
- Any provider defined through a string token (e.g. @ViewChild('someToken') someTokenVal: any)
- A TemplateRef (e.g. query with @ViewChild(TemplateRef) template;)
The 1, 2 and 5 are most commonly known and used. In this write up I will be exploring 3 and 4. So let's get started!
Accessing Child Component Provider Without Injecting.
Suppose you have a component called Parent component inside which there is another component called child. Child Component injects a service inside it called RandomNumberService
which has method called getRandomNumber
this method return a random number. This service is provided in Child's components decorator metadata
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
providers: [RandomNumberService],
})
Service injected via this method is not singleton. For each instance of child component a new instance RandomNumberService
will created. So if we want to access this service we will need to use ViewChild
, lets see how we can use it.
export class ParentComponent implements OnInit {
@ViewChild(RandomNumberService) randomNumberService: RandomNumberService;
constructor() { }
ngOnInit() {
}
ngAfterViewInit() {
console.log(this.randomNumberService.number);
}
}
We can achieve the same result by accessing the child component's instance and then accessing the service but then we would have to make sure that the service instance variable is public otherwise it won't work so to avoid that we can use ViewChild
with service.
Now lets take at point 4 which is
Accessing Any Provider Defined Through A String Token.
Moving forward with previous example suppose that inside child component you have provider defined in following way:
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
providers: [{provide: 'TokenName', useValue: 'Foo Bar'}],
})
and now you need to access it. You can use the following format of ViewChild
export class ParentComponent implements OnInit {
@ViewChild('TokenName') token: RandomNumberService;
constructor() { }
ngOnInit() {
}
ngAfterViewInit() {
console.log(this.token); // logs 'Foo Bar'
}
}
Thats all for now!. Let me know how you use angular decorators and what are your favourite tips and tricks, and do let me know if missed anything.
Thanks for reading!
cover image credits: https://unsplash.com/photos/1seONCyPWfQ
Posted on July 27, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.