Angular jqLite on $destroy not working - javascript

I have a div called MyDiv and am bootstraping Angular manually to it (due to some limitations from a legacy system). In a particular case, I would like that on $destroy I do some further processing. I am using the below snippet, however it seems that it doesn't trigger anything - the console logging is not working :(
angular.element(document.querySelector('#MyDiv')).on('$destroy', function() {
// do something
console.log("test");
});
Can someone tell me what I am doing wrong? This is the first time I am relying on jqLite as usually I use the full jQuery. I am using this in a controller not a directive.
Additional Detail:
I've also tried using the below, however I get this error in the console: Error: [jqLite:nosel] Looking up elements via selectors is not supported by jqLite!. This used to work when I was loading AngularJS after jQuery but i had to change the order to load angular first, and therefore have to rely on jqLite.
angular.element('#MyDiv').on('$destroy', function() {
alert("Test");
});
Note - if there is a way to do this using native js that is fine.
Thanks

Related

How does angular determine whether jQuery is present?

Because I'm getting the weird situation that angular objects like element in the link function of a controller ends up being a jQLite object although jQuery is definitely present as in being loaded in memory and successfully used elsewhere on the same page.
The Angular FAQ is rather vague on that question:
Yes, Angular can use jQuery if it's present in your app when the application is being bootstrapped. If jQuery is not present in your script path, Angular falls back to its own implementation of the subset of jQuery that we call jQLite.
So what exactly does 'present' mean?
Angular.js will use jQuery if it's included first, otherwise it will use it's own jqLite. If you load jQuery after AngularJS, AngularJS attaches itself to jqLite but you can still access jQuery through $.
See below the code used by angular.js to determine if jquery is loaded:
// bind to jQuery if present;
jQuery = window.jQuery;
// Use jQuery if it exists with proper functionality, otherwise default to us.
// Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
// Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
// versions. It will not work for sure with jQuery <1.7, though.
if (jQuery && jQuery.fn.on) {
jqLite = jQuery;
extend(jQuery.fn, {
scope: JQLitePrototype.scope,
isolateScope: JQLitePrototype.isolateScope,
controller: JQLitePrototype.controller,
injector: JQLitePrototype.injector,
inheritedData: JQLitePrototype.inheritedData
});
Changing the order of script tags may not happen very often, but it could occur if you start modularising the codebase. In particular, this issue has happened while using some module loaders like RequireJS.

Rails/Javascript selectors won't find elements

I am in the process of installing the asset pipeline into an older rails app. I am getting some really strange results though. I can see that the page is rendering all of the css and the jquery that is in the app/assets directory but its having a hard time interacting with the html.
For instance if i inspect the page and in the console call $("html").html(); to try grab all the html it returns TypeError: Cannot call method 'html' of null same when trying to grab any element that is being rendered? but the page is there. if i call jQuery it will return fine. so its not like it jQuery isnt there.
$ is just a shorthand way of writing jQuery. If the latter works but the former doesn't, then another script in your pipeline is probably conflicting with jQuery and trying to use the $ symbol for something else.
Are you using any other plugins or libraries that might be trying to use $? Or have you accidentally overwritten it yourself by writing $ = (something) anywhere? Without more information it's hard to know where the problem is exactly.
If all else fails you can just stick to using jQuery() for all your calls. In your external script file you could also circumvent this by passing the jQuery object to a wrapper function, e.g.:
(function ($) {
$('div').append('You can use $ here without having to worry about conflict.');
}(jQuery))

Export Angular JQLite as $/jQuery

I occasionally find plugins that try to detect if JQuery is present, or might have 1-2 lines of code that uses $. I am wondering if it's possible to make Angular's JQLite available outside of angular apps somehow? My first tries of simply seeing if JQLite was available did not work. Basically I would like either the variable $ or jQuery to be available anywhere (or at least within my ng-app area) to see if it contains enough functionality to let these jquery plugins/code work.
Here's the source https://github.com/angular/angular.js/blob/master/src/jqLite.js
Actually, you can, but it almost certainly won't help.
If you wanted to "export" it, you'd simply need to add this after the Angular JavaScript is loaded:
window.jQuery = window.$ = angular.element;
Now calling $() or jQuery() will run jqLite. Here's why it most likely won't work: jqLite doesn't support selectors, meaning you can't do
angular.element('.foo').html();
You'll just get an error stating that Selectors not implemented.
Here's a jsFiddle showing it working when used on elements directly, but failing with the selector.
Edit
Based on Yashua's suggestion below, here's an update using his trick to enable selectors. It's a nice trick/hack if jqLite is good enough.
Personally, I don't agree that you should just include jQuery. It's another large library to depend on, and if you are only performing a couple of one-liners, you should be able to integrate them into Angular directly using proper directives. I'd take the time to see if you can rewrite the existing code.

Minified JS only works by pasting source into Controller

I'm not sure if there is a clear way for me to show / describe the problem that I'm having. But here goes:
I've developed an app with AngularJS (have not put live yet). It was decided that we needed tooltips for some of the metrics on the tables. We liked the general look of TipTip jQuery Plugin.
On my index file I correctly include the minified.js:
<script src="../assets/javascripts/app/jquery.tipTip.minified.js"></script>
(yes, the path is correct. I can click on the link in chrome developer tools and see the source file).
In my controller, I call it with this:
$scope.addTolltips = function() {
$timeout(function(){$('.results-metrics').tipTip({maxWidth:"300px", defaultPosition: "top"});},500);
}
I added the $timeout to make sure there was enough time for dynamic stuff on the page to be load in the DOM. I know it's probably not necessary anymore though.
But when tipTip() is being called I get a console error:
TypeError: Object [object Object] has no method 'tipTip'
However, if I take the minified source and paste it into my controller before the tipTip(), then everything works perfect. Any thoughts?
angularjs provides jQuery functionality via the angular.element function (http://docs.angularjs.org/api/angular.element), so you should use it instead of $ (however, I cannot explain why $ isn't working in your case)

no method domReady error in console even though domReady gets called

I'm new to Javascript so forgive me if I kill this question.
I've got a script to grab my latest twitter posts and place it on my blog:
http://www.joshkerr.com
It isn't working. The error I see in the console is "no method domReady." Yet another script I wrote runs just fine and if I step through my function, works fine.
Here is the strange part. If I include jquery further up in my file, I get the Twitter object working, but my search http://www.joshkerr.com/search/ stops working. So I suspect some kind of namespace issue going on.
How do I get my Twitter object to work again?
Since It is all client code, you can view source and see for yourself.
It looks like jeesh.min.js may be clobbering jQuery's $ object. Your search page throws the error "Object function h(a,b){return g(a,b)} has no method 'getJSON'". The jeesh.min.js file contains "function h(a,b){return g(a,b)}" and getJSON is a jQuery method, so there you go. I see your search page contains a block like
$(document).ready(function() {
// Your code here
});
It's usually considered good practice to wrap such code like so
(function($) {
$(document).ready(function() {
// Your code here
});
})(jQuery);
This ensures that $ is actually the jQuery object.

Categories

Resources