angular: Pipes break when used in a ng-switch-default

When using a custom pipe inside of an ng-switch-default the pipe breaks with the exception:

EXCEPTION: TypeError: Cannot read property 'constructor' of undefined in [null]

TypeError: Cannot read property 'constructor' of undefined
    at Object.implementsOnDestroy (
    at Function.ChangeDetectionUtil.callPipeOnDestroy (
    at AbstractChangeDetector.ChangeDetector_Hello_5.dehydrateDirectives (eval at <anonymous> (, <anonymous>:93:49)
    at AbstractChangeDetector.dehydrate (
    at AppViewManagerUtils.dehydrateView (
    at AppViewManager_._viewDehydrateRecurse (
    at AppViewManager_._destroyViewInContainer (
    at AppViewManager_.destroyViewInContainer (
    at ViewContainerRef_.remove (
    at ViewContainerRef_.ViewContainerRef.clear ( @ @ function) @ @ @ @ function) @ @$es6$promise$asap$$flush @
2015-11-06 15:24:17.011 ERROR CONTEXT:BrowserDomAdapter.logError @ @ function) @ @ @ @ function) @ @$es6$promise$asap$$flush @

Here is a plunker: When I remove the ng-switch-default template, I don’t get the error.

Using Chrome 46 on Mac.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 10
  • Comments: 21 (5 by maintainers)

Commits related to this issue

Most upvoted comments

@laurelnaiad Figured it out

<script src="node_modules/systemjs/dist/system.src.js"></script>
        System.register("angular2/src/core/change_detection/pipe_lifecycle_reflector", [], true, function(require, exports, module) {
            exports.implementsOnDestroy = function(pipe) { return pipe ? pipe.constructor.prototype.ngOnDestroy : false };

This did it for me.

I simplified @Xesued’s reproduction – no custom pipe appears needed, just ensure ngFor keeps an unused branch so it tries to destroy a pipe that didn’t get initialized. I wasn’t able to reproduce with @Ristaaf’s optional pipe though. I’m a bit confused though, since in @Xesued’s example all ngFor branches do get used by different entries… but the common thread seems sorta clear.

So the crash occurs here, due to pipe ending up undefined. I think this could be patched as follows:

function implementsOnDestroy(pipe: any): boolean {
    // return pipe.constructor.prototype.ngOnDestroy;
    return pipe ? pipe.constructor.prototype.ngOnDestroy : false;

(For debugging I also tried to add a print statement in the parent stack level; here selectedPipe turned out as {}😃

    ChangeDetectionUtil.callPipeOnDestroy = function (selectedPipe) {
        console.log('callPipeOnDestroy:selectedPipe', selectedPipe);
        if (pipe_lifecycle_reflector_1.implementsOnDestroy(selectedPipe.pipe)) {

I’m having trouble locally running the tests to verify this null check fixes the issue without messing up other things though; perhaps someone else would be able to try that…

Edit: to clarify, I haven’t verified if suppressing the error makes things work as desired; on my own code I still had an unrelated error I was already getting on other code as well, while with Plunker I’m not sure I can just alter the ng2 code like this, so I haven’t actually seen the result.