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

fix(jqLite.cleanData): TypeError: Cannot read property 'events' of undefined #16641

Closed
alextkachman opened this issue Jul 22, 2018 · 7 comments
Closed

Comments

@alextkachman
Copy link

alextkachman commented Jul 22, 2018

I'm submitting a ...

  • [x ] bug report

Current behavior:
TypeError happens when data is cleaned for OBJECT element. OBJECT does not support data

Expected / new behavior:
no TypeError expected

Minimal reproduction of the problem with instructions:
OBJECT element removed by because of ng-if instruction

        <div ng-if="shownGraphic.tag === 'multimedia' && shownGraphic.multimediaObject.multimediaType === 'swf'" style="width: 100%; height: 100%;">
            <object style="width: 100%; height: 100%;"><embed style="width: 100%; height: 100%;" embed-src="{{shownFigureView.url()}}" /></object>
        </div>

AngularJS version:
Angular 1.7.2
JQuery 1.10.2

Browser:
Presumably All

Anything else:
TypeError: Cannot read property 'events' of undefined
at Function.jqLite.cleanData (angular.js:2051)
at replaceWith (angular.js:10704)
at applyDirectivesToNode (angular.js:9768)
at compileNodes (angular.js:9293)
at compileNodes (angular.js:9305)
at compileNodes (angular.js:9305)
at compileNodes (angular.js:9305)
at compile (angular.js:9174)
at Object.link (angular.js:28966)
at angular.js:1364

@gkalpak
Copy link
Member

gkalpak commented Jul 22, 2018

This is a jQuery 1.x issue. Not sure which version it was fixed in, but jQuery 3.x (as well as AngularJS' built-in jqLite) always return an object.

@alextkachman
Copy link
Author

This is so wrong. It for years worked correctly elem._data('events') and recently was changed to incorrect elem._data().events with no obvious for me reason

@gkalpak
Copy link
Member

gkalpak commented Jul 22, 2018

Hm...OK if we can fix this is a non-breaking way, then there is little reason not to, I guess 😃

It was changed in b7d396b.
@mgol, any objection against reverting jqLite._data(elem).events to jqLite._data(elem, 'events')? Is this going to affect the behavior with latest jQuery?

@mgol
Copy link
Member

mgol commented Jul 22, 2018

@alextkachman AngularJS hasn't supported jQuery 1.x since version 1.3 if I remember correctly. This version was released almost 4 years ago. Your configuration has been unsupported for a long time so something may randomly break even in a patch release; we can't prevent that from happening as we don't run unit tests with jQuery 1.x. You should move to a supported version of jQuery, i.e. 2.1 or newer.

@gkalpak We can't just revert the change as jqLite doesn't support the two-param _data signature and the linked commit changed the cleanData patch to be performed on jqLite in addition to jQuery. That's why I changed this line.

Fixing this issue requires to do one of the following:

  1. fork the logic inside of the patch for jQuery & jqLite
  2. add support for the two-param _data to jqLite
  3. add a check for jQuery._data(elem) being defined before accessing its events property

I think what happens is jQuery 1.x uses jQuery.cleanData inside jQuery#remove internally where it removes the cache entry for the removed node before calling jQuery.cleanData, making jQuery._data(elem) return undefined inside of our patched jQuery.cleanData. In all other cases, even jQuery 1.x should be falling back to an empty object if there are no handlers attached.

@gkalpak
Copy link
Member

gkalpak commented Jul 22, 2018

Thx for the info, @mgol. Although jQuery 1.x is indeed not supported, I think option (3) is harmless (and straight forward). I'll submit a PR.

gkalpak added a commit to gkalpak/angular.js that referenced this issue Jul 22, 2018
This shouldn't happen in supported jQuery versions (2+), but if someone
uses the unsupported 1.x version the app will break. The change that
causes this new behavior was introduced in b7d396b.

Even though jQuery 1.x is not supported, it is worth avoiding the
unnecessary breakage (given how simple).

Fixes angular#16641
gkalpak added a commit to gkalpak/angular.js that referenced this issue Jul 22, 2018
…rns undefined

This shouldn't happen in supported jQuery versions (2+), but if someone
uses the unsupported 1.x version the app will break. The change that
causes this new behavior was introduced in b7d396b.

Even though jQuery 1.x is not supported, it is worth avoiding the
unnecessary breakage (given how simple).

Fixes angular#16641
gkalpak added a commit that referenced this issue Jul 23, 2018
…rns undefined

This shouldn't happen in supported jQuery versions (2+), but if someone
uses the unsupported 1.x version the app will break. The change that
causes this new behavior was introduced in b7d396b.

Even though jQuery 1.x is not supported, it is worth avoiding the
unnecessary breakage (given how simple).

Fixes #16641

Closes #16642
@mgol
Copy link
Member

mgol commented Jul 23, 2018

Yes, I forgot to add option 3 sounded the best to me as well as it's such a critical place and such an easy fix.

@alextkachman
Copy link
Author

Thank you, @gkalpak and @mgol

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

No branches or pull requests

3 participants