Angular.js: 1.5.8 breaks with jQ 3.1.1 w/ Migrate 3.0.0 due to using an undocumented API in jQuery.data

Created on 6 Nov 2016  路  6Comments  路  Source: angular/angular.js

Angular 1.5.8 replaceWith uses copy the associated jQuery data of the DOM element into another by using

jqLite.data(newNode, jqLite.data(firstElementToRemove));

If jQuery is present on the page, then it will be used instead of the bundled jqLite. However a problem arises when jQuery 3.1.1 is used alongside jQuery Migrate 3.0.0. It turns out that the outer call working in the first place with previous versions of jQuery was just a fluke. According to the documentation, if 2 arguments are passed to jQuery.data, the second argument must be a string; and there is no support for passing in an object. This is unlike .data() which since 1.4.3 is documented to accept an object.

To reproduce

My ng-fu is not too good to make a minimal example, but it is reproduceable by this Plunker; I took the working example from ui-select and added jQuery 3.1.1 and jquery-migrate 3.0.0 (and reset the angular version to 1.5.8). Upon running, the following error log is produced for each select box rendered by ui-select (and the select boxes themselves wouldn't work):

Error: string.replace is not a function
.camelCase@https://code.jquery.com/jquery-3.1.1.js:355:10
jQuery.data@https://code.jquery.com/jquery-migrate-3.0.0.js:306:24
replaceWith@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:9908:9
compileTemplateUrl/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:9663:15
processQueue@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:16383:28
scheduleProcessQueue/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:16399:27
$RootScopeProvider/this.$get</Scope.prototype.$eval@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:17682:16
$RootScopeProvider/this.$get</Scope.prototype.$digest@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:17495:15
$RootScopeProvider/this.$get</Scope.prototype.$apply@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:17790:13
bootstrapApply@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:1761:9
invoke@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:4718:16
bootstrap/doBootstrap@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:1759:5
bootstrap@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:1779:12
angularInit@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:1664:5
@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js:31763:5
resolve/</mightThrow@https://code.jquery.com/jquery-3.1.1.js:3570:21
resolve/</process<@https://code.jquery.com/jquery-3.1.1.js:3638:12
angular.js:13920:18

It would be preferable if the undocumented behaviour wasn't relied upon since more and more people will need to integrate some legacy Angular 1 with something that requires jQuery 3, and these kinds of errors are all too confusing. Another possibility would be to push this behaviour to be added into jQuery Migrate 3.0.0 but I am not too sure it would get accepted.

jqLite low feedback investigation broken expected use bug

Most helpful comment

https://github.com/jquery/jquery-migrate/issues/198 has been fixed; the next Migrate release will include it.

All 6 comments

So, @mgol, does it mean that if jquery/jquery-migrate#198 gets fixed, we don't need to change anything in Angular? Or do we need to fix something (e.g. in 1.6.x) to be compatible with jQuery 3.x?

Yes, we'll fix this in Migrate. While technically it's an undocumented feature, it might be that a lot of code actually depends on it so it makes sense to patch in Migrate regardless.

We'll think if we want to unprivatize this API in jQuery.

I'll close this issue since we won't be applying any changes to Angular.

@gkalpak Note that this issue only occurs if you use Angular with jQuery 3 + Migrate 3; it works fine with just jQuery 3 and we have tests to prove it. :)

We don't run tests with Migrate but the purpose of Migrate is to ease code migration and remove it afterwards, it shouldn't be running on production for too long.

https://github.com/jquery/jquery-migrate/issues/198 has been fixed; the next Migrate release will include it.

@ztane Could you make sure the development version of Migrate fixes your issue?

Was this page helpful?
0 / 5 - 0 ratings