maxisam/ngx-clipboard

`TypeError: this.clickListener is not a function`

junglebarry opened this issue · 0 comments

When running tests for components that embed ngx-clipboard I get the following:

ERROR: 'Error during cleanup of component',...

and:

TypeError: this.clickListener is not a function
    at ClipboardDirective.ngOnDestroy (http://localhost:9876/_karma_webpack_/node_modules/ngx-clipboard/__ivy_ngcc__/fesm2015/ngx-clipboard.js:216:1)
    at executeOnDestroys (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9261:1)
    at cleanUpView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9185:1)
    at destroyViewTree (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9018:1)
    at destroyLView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9163:1)
    at RootViewRef.destroy (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9777:1)
    at ComponentRef$1.destroy (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:24147:1)
    at ComponentFixture.destroy (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:330:1)
    at http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:2052:1

This is not causing a test failure; it's just reporting this issue during component cleanup.

It looks from the code like this function is initialised during ngOnInit, but using some ngZone magic to run in the root zone:

public ngOnInit() {
this.ngZone.runOutsideAngular(() => {
// By default each host listener schedules change detection and also wrapped
// into additional function that calls `markForCheck()`. We're listening the `click`
// event in the context of the root zone to avoid running unnecessary change detections,
// since this directive doesn't do anything template-related (e.g. updates template variables).
this.clickListener = this.renderer.listen(this.host.nativeElement, 'click', this.onClick);
});
}

My guess is that for whatever reason, the tests have not fully initialised this before they fail and complete, so when the component cleanup runs:

public ngOnDestroy() {
this.clickListener();
this.clipboardSrv.destroy(this.container);
}

... the value of this.clickListener has never been initialised, hence the error.

I'm happy to raise a PR to address this (maybe initialise with an empty function; or check it's defined before executing), but wanted to check whether there's something deeper I'm misunderstanding before doing so.

It's certainly not happening in all my component tests; just a subset where there's quite a lot of behaviour being tested ("integration" tests of top-level routed components). The tests are not related to ngx-clipboard, either; rather it's reporting on all tests for that component.