5

I am working on a small Greasemonkey script to speed up some processes in a vendor's tool that is written in angularJS.

The issue I seem to be facing is that the element is not in the DOM when the script runs:

$(document).ready(function() {
  var pwEl = $("input:password").val(chance.word({length: 8});
};

fails because the input field does not seem to be present when (document).ready() runs. There have been a few resources that seem to confirm this.

Is there a way that I can wait for Angular to finish before running my script? I have found references to using:

angular.element(document).ready(function() {
  console.log("Hi from angular element ready");
});

However, this never seems to execute either.

I'm really new to Angular (I've only played around with a few short tutorials). Any direction is appreciated.

Thank you!

Tim AtLee
  • 917
  • 1
  • 10
  • 17
  • I think you're looking for the code detailed here. [Sending event when angular.js finished loading](http://stackoverflow.com/questions/14968690/sending-event-when-angular-js-finished-loading) – Andy Hoffman Apr 25 '16 at 18:36
  • There's no good 'way that I can wait for Angular to finish' except for lame `setTimeout(..., 5000)`, because Angular app doesn't finish loading at specific moment of time. The moment when `input:password` elements appear depends on how the directives that create them work. The best way is to hijack Angular bootstrapping process and decorate app services. – Estus Flask Apr 25 '16 at 18:47

1 Answers1

6

Wait for the element to actually be added by using timers, MutationObserver, or a utility like waitForKeyElements().

Here's a complete Greasemonkey script showing one way:

// ==UserScript==
// @name     _Process nodes after Angular adds them
// @match    http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/BrockA/2625891/raw/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
//- The @grant directive is needed to restore the proper sandbox.

waitForKeyElements ("input:password", actOnNode);

function actOnNode (jQueryNode) {
    //--- Do whatever you need to on individual nodes here:
    // For example:
    jQueryNode.css ("background", "orange");
}
Brock Adams
  • 90,639
  • 22
  • 233
  • 295