Angular.js

Accessing a Child Component’s Public Scope in Angular

I was asked to create an autocomplete component that would do some filtering on a list and include a “clear” button that could reset this filter. Not a problem, if it wasn’t for the fact that it was this Angular newbie’s first ever Angular story in an Angular 4 project. #Angular

In a React-Redux setup (which is what I’m used to), managing values is a matter of working with Redux. Resetting a value would mean dispatching an action that empties a certain part of your application state; in this case, the value of the allLabels input:

<search-filter
    id="allLabels"
    name="allLabels"
    flyoutSize="full"
    flyoutAlign="right"
    label="Find stuff"
    labelDeselect="Clear stuff"
    labelResults="Found stuff"
    labelNoResults="Couldn't find stuff!"
    placeholder="Look for stuff"
    inputDelay="0"
    [choices]="stuff"
    [showAllByDefault]="true"
    [remote]="true"
    (search)="findStuff($event)"
><search-filter>

label angular

The API of this component did not seem to expose a way to modify the value like you would with a normal input using, for example, ngModel. Additionally, in our case, this is a third party component, which means we cannot alter its codebase.

When looking at the component’s internal code, it’s fairly easy to figure out that the public “reset” method would reset the value. After attempting this, however, it didn’t seem possible (to me) to access this method.

this.categoryFilter.value = ‘’; // nopetynope
this.categoryFilter.reset(); // nopes

A colleague who is wise in the ways of Angular presented the solution to me:
“Just use a viewchild decorator.”

Looking at the documentation, though, I was none the wiser. What is it? What does it do? How do I use it? #clueless

The viewchild decorator

Thankfully, my colleague (who soothed my ego by saying the documentation “might not be very clear”) explained it to me. Allow me to explain!

First, there’s the matter of referencing the component:

<search-filter
   #categoryFilter
   id="status"
… />

Then, we “couple” this reference with a viewchild decorator. (Not coming from an OOP background, the concept of decorators was also new to me, but it’s fairly easy to understand when you read up about it.)

@ViewChild('categoryFilter') categoryFilter: SearchFilterComponent;

This allows us to reference any “public” methods or properties of our categoryFilter component – for example, the “clear” method!

this.categoryFilter.clear(); // does the clearing!

So, putting it all together it looks like this:

<searchFilter.component.html>
<search-filter
   #categoryFilter
   id="status" />
...
<button title="clear categories" (click)="clearCategories()">clear</button>
...
<searchFilter.component.ts>
@Component({
    selector: 'search-filter',
    templateUrl: './searchFilter.component.html',
    styleUrls: ['./searchFilter.component.css']
})
export class SearchFilter implements OnInit {
    @ViewChild('categoryFilter') categoryFilter: SearchFilterComponent;
...
clearCategories(): void {
    this.categoryFilter.clear(); // does the clearing!
}
...
}

The viewchild decorator is a useful pattern in cases where you need to reference (and call) a child component(‘s methods), but can’t alter the codebase for whatever reason. Do you know of an alternative, or even a better way? Feel free to let us know.

Published on Web Code Geeks with permission by Jeroen Savat, partner at our WCG program. See the original article here: Accessing a Child Component’s Public Scope in Angular

Opinions expressed by Web Code Geeks contributors are their own.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button