Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Angular 1.2+, jQuery 2.1+, jQuery UI 1.x+ include order
If you're using Angular 1.2+, jQuery 2.1+, jQuery UI 1.x+ together, you can easily get a weird error like this:
TypeError: undefined is not a function
at replaceWith (http://myapp.com/app/bower_components/angular/angular.js:7289:26)
at applyDirectivesToNode (http://myapp.com/app/bower_components/angular/angular.js:6518:13)
at compileNodes (http://myapp.com/app/bower_components/angular/angular.js:6167:15)
at compileNodes (http://myapp.com/app/bower_components/angular/angular.js:6179:15)
at compile (http://myapp.com/app/bower_components/angular/angular.js:6107:15)
at http://myapp.com/app/bower_components/angular/angular.js:1506:11
at Scope.$eval (http://myapp.com/app/bower_components/angular/angular.js:12903:28)
at Scope.$apply (http://myapp.com/app/bower_components/angular/angular.js:13001:23)
at Scope.$delegate.__proto__.$apply (<anonymous>:855:30)
at http://myapp.com/app/bower_components/angular/angular.js:1504:15
Probably you're include jQuery before Angular in your html file like this:
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
....
<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>
It's kinda hard to track down type error, since what is hitting is that jQuery defines a cleanData function,
then Angular overrides it and stores the original function in $$original so it can call it in the chain.
Angular is caring when overriding, so its a nice thing.
Guess what, jQuery UI defines its own cleanData function, its also nice, since it does save the previous function into _cleanData.
Maybe at this point you guess something.....yes, there will be no $$original and when Angular tries to invoke that...if will miserable fail and you get the above stacktrace (1.3.0-beta17).
So the solution is simple, you've to take care and workaround this by including the components in the "right" order:
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>
<script src="bower_components/angular/angular.js"></script>
Who is the bad guy here? Angular...the proper solution would be from Angular's side if it should not depend on cleanData.$$original outside of its own cleanData function.
In this case replaceWith is invoking the jQuery.cleanData.$$original function.
IMHO the solution would be fairly simple, store the $$original within some Angular territory and NOT on Angulars cleanData override function, since it can easily disappear from there in the JavaScript world.
Sorry for giving you this as a Gist, but I'm working on my blog's design and sitebuild....
I hope it helps some of you.
@brnstz

This comment has been minimized.

Copy link

@brnstz brnstz commented Aug 4, 2014

Thanks very much for this post. Saved my day. I didn't use your ordering trick, but instead set my angular version to "1.3.0-build.2969+sha.92a10d8", which was our last stable build.

@ee0pdt

This comment has been minimized.

Copy link

@ee0pdt ee0pdt commented Aug 8, 2014

Thanks! Was tearing my hair out! Like brnstz I set my angular version manually as reordering wasn't an option for me (Jquery UI isn't in my project directly but some plugin uses it somewhere).

@mgol

This comment has been minimized.

Copy link

@mgol mgol commented Aug 14, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment