Angular 2+ how to detect if ng-content ContentChild element implements an interface

331 views Asked by At

Am writing an Angular 2+ component which provides "dressing" for some other contained component (provided as the ng-content tag).

For example:

<my-container>
    <your-component></your-component>
</my-container>

The your-component becomes the ContentChild inside of the TypeScript my-component code.

However, if I can somehow detect the component and ask it if it implements a certain interface (we'll call it ICanHelpMyComponentDoItsJobBetter), then the my-component code can activate certain additional features.

I have not been able to figure out how to answer the question "Do you implement the ICanHelpMyComponentDoItsJobBetter interface?" inside of my-component when looking at its ContentChild. If it does, I want to cast it as that interface instance and make additional calls or set other properties.

Any help would be appreciated -- this is obviously an advanced Angular question. Thanks!

Adddional Info (May 4, 2021):

As my your-content tag does not contain a selector (and I'd rather not force my users to specify one), I have no way of using @ContentChild('xxx') in the TS file. So that has been a problem -- I don't know how to turn that into a usable member in my TS code.

Another thing I tried was to create a @ViewChild element around the ng-content, like this:

<div #ngContentDiv>
    <ng-content></ng-content>
</div>

So now I can have this in my .ts file: @ViewChild('ngContentDiv') ngContentDiv: ElementRef;

And then later, in ngAfterContentInit() when things are all initialized, I can ask: this.ngContentDiv.nativeElement.children[0]

and this is the element -- but I can't seem to figure out how to do anything with that.

Obviously if there were a way to get this directly into @ContentChild, that would be better, but I've still managed to work my way to the element in question and when I inspect it, it is indeed the element I indicated in my test case.

I've tried casting that as an instance of the interface -- no luck. I've tried using @ContentChildren with a custom directive and then attempting to call its methods -- still nothing.

No rush here, but I'm scratching my head -- that component is there -- if I can cast it somehow to something it implements, I can finally ask it to help facilitate its presentation -- obviously many won't implement the interface, but I don't care about those.

1

There are 1 answers

0
Yoan Asdrubal Quintana Ramírez On

You can try checking if the component has your feature implementation

// Check if the component has property i am interested and check if that property is a function

if(!!this.myCustomContentChild['myCustomFeature'] && typeof this.myCustomContentChild['myCustomFeature'] === 'function' ) { 

// then call function

this.myCustomContentChild['myCustomFeature']();

}