Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ngAnimate throws exception in cancelChildAnimations on deletion of repeated element when using ng-include #4548

Closed
gregolsky opened this issue Oct 20, 2013 · 9 comments
Assignees

Comments

@gregolsky
Copy link
Contributor

Here's plunker http://plnkr.co/edit/HrmBBmz949YnS7IcPyp7?p=preview
Please try to click one of the "Remove this" links.
I attach stack trace just in case.

TypeError: Object # has no method 'querySelectorAll'
at cancelChildAnimations (http://code.angularjs.org/1.2.0-rc.3/angular-animate.js:593:36)
at Object.leave (http://code.angularjs.org/1.2.0-rc.3/angular-animate.js:332:11)
at ngRepeatAction (http://code.angularjs.org/1.2.0-rc.3/angular.js:17770:24)
at Object.$watchCollectionAction as fn
at Scope.$digest (http://code.angularjs.org/1.2.0-rc.3/angular.js:10569:27)
at Scope.$apply (http://code.angularjs.org/1.2.0-rc.3/angular.js:10802:24)
at HTMLAnchorElement. (http://code.angularjs.org/1.2.0-rc.3/angular.js:16514:17)
at http://code.angularjs.org/1.2.0-rc.3/angular.js:2331:10
at Array.forEach (native)
at forEach (http://code.angularjs.org/1.2.0-rc.3/angular.js:213:11)

@gregolsky
Copy link
Contributor Author

The error occurs, when the "element" argument passed to the cancelChildAnimations function contains comment element (at index 0), which does not have the querySelectorAll method. The fix may be to check, if the element supports the method in question.

@matsko
Copy link
Contributor

matsko commented Oct 22, 2013

I see what's going on here. I also got your email yesterday outlining the issue. Thanks for sending that over, I wouldn't have noticed this as quickly.

Checking for querySelectorAll does fix it, but you want the code to be as informative as possible. What's going on is that the comment node (which ngInclude uses) is being animated and that's where it breaks.

So just check for element[0].nodeType == ELEMENT_NODE.

Can you update your pull request to handle that check? Basically something like:

function cancelChildAnimations(element) {
  var ELEMENT_NODE = 1;
  var node = element[0];
  if(node.nodeType == ELEMENT_NODE) {
    angular.forEach(node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME), function(element) {
      element = angular.element(element);
      var data = element.data(NG_ANIMATE_STATE);
      if(data) {
        cancelAnimations(data.animations);
        cleanup(element);
      }
    });
  }
}

Once ready I can merge it in directly.

@ghost ghost assigned matsko Oct 22, 2013
gregolsky added a commit to gregolsky/angular.js that referenced this issue Oct 22, 2013
fix ngAnimate throwing exception in cancelChildAnimations on deletion of
element (ngAnimate's leave decorator) of repeated element when using
ng-include on this element.

Closes angular#4548
@matsko matsko closed this as completed in b9557b0 Oct 22, 2013
@matsko
Copy link
Contributor

matsko commented Oct 22, 2013

Landed as b9557b0

jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
fix ngAnimate throwing exception in cancelChildAnimations on deletion of
element (ngAnimate's leave decorator) of repeated element when using
ng-include on this element.

Closes angular#4548
jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
fix ngAnimate throwing exception in cancelChildAnimations on deletion of
element (ngAnimate's leave decorator) of repeated element when using
ng-include on this element.

Closes angular#4548
@thaoula
Copy link

thaoula commented Feb 2, 2014

Hi Guys,

This error is still happening in version 1.2.10 and every version since the issue was reported.

I always have to check if the following line is undefined -

function cancelChildAnimations(element) {
var node = extractElementNode(element);

Regards,
Tarek

@caitp
Copy link
Contributor

caitp commented Feb 2, 2014

@thaoula, can you provide some information on which nodes you're running into this on? It wouldn't totally surprise me if certain XML interfaces didn't implement this

@matsko
Copy link
Contributor

matsko commented Feb 2, 2014

This is a common issue with ngAnimate and this PR fixes it: #5570.

Waiting to merge in the class-based animation fix first since it has a bit of an internal refactor. That will happen next week.

@caitp
Copy link
Contributor

caitp commented Feb 2, 2014

I thought the nodeType test in cancelChildAnimations was already merged.

@matsko
Copy link
Contributor

matsko commented Feb 2, 2014

The problem occurs when an empty jqLite element shows up (when all it has are comment nodes within and no element node). The PR fixes it in a way that avoids the constant checking for comment nodes during the animations.

@robations
Copy link

I know this issue is old and closed but I'm still seeing this issue with v1.3.15 and OS X Safari.

The problem seems to be element passed from cancelChildAnimations --> extractElementNode is an array-like object (it has a length) but the keys are not numerical:

Object.keys(element)
["1", "length", "[object HTMLLabelElement]"]

element.length
2

Obviously iterating through this using a for-loop fails. element["1"] is a comment node created by ngRepeat.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants