I am writing an AngularJS web app and have a function outside of any scope that needs to call a function inside of a scope. I call the function and follow the instructions given in this answer.
function returnDest(callback) {
$(document).ready(angular.element(document.getElementById('body')).scope().getTask(function() {
if(callback) {
callback(locationInfo);
}
}));
}
It works often, but sometimes the function does not successfully run. A debugger gives me:
Uncaught TypeError: Cannot read property 'getTask' of undefined
I do not know why the function is being called on undefined when $(document).ready should have the function fire only after the DOM has been loaded. The same error pops up if I use $(window).load(). What can I do to ensure this function runs successfully?
For reference, here is the line in the HTML file where the 'body' element is defined
<body style="background-color:#e6e8f3" ng-app="app" ng-controller="controller" id="body">
$(document).ready should be outside of your function:
$(document).ready(function returnDest(callback) {
angular.element(document.getElementById('body')).scope().getTask(function() {
if(callback) {
callback(locationInfo);
}
})});
You're using .ready incorrectly. The moment you call returnDest, which is happening before the DOM is ready, it tries to get an element with the ID of body. Since it's not loaded, body can't be accessed. Instead, omit the body ID and use it like this:
function returnDest(callback) {
$(document).ready(function() {
angular.element(document.body).scope().getTask(function() {
if (callback) {
callback(locationInfo); // Not sure where locationInfo is coming from
}
});
});
}
angular.element returns a jQuery object.
ready() expects the argument you pass it to be a function that it will call when the document is ready.
It sounds like you need to wrap everything you are trying to pass to ready in function () { ... }.
Related
I was wondering how to use the $(this) selector in a function. I have tried multiple ways found on the internet but none seem to work.
Here's an example of what I'm trying to do
function bobsCar() {
$(this).toggle();
}
$('p').click(function() {
bobsCar();
});
Another option is to execute the function with a custom context like.
function bobsCar() {
$(this).toggle();
}
$('p').click(function() {
bobsCar.call(this);
});
In your case since you are calling bobsCar without a context, this inside it refers to the window object that is why it is not working.
Function.call()
function bobsCar() {
$(this).toggle();
}
jQuery('p').click(function() {
bobsCar.call(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>click me</p>
You need to understand JavaScript contexts. By default if you call a method inside your click callback, it will use the global context (in this case window - try console logging this in your broken function), not the one in the callback. You can use call or apply to specify the context (in this case this refers to the DOMNode element in the callback, so we pass the same context to the function and it works).
This is a good article on the topic: http://yehudakatz.com/2011/08/11/understanding-JavaScript-function-invocation-and-this/
The value of this inside the click event handler is not a string representation of a selector. It is a DOM node.
If you want to override the normal value of this for a function, you can specify it with call or apply.
bobsCar.call(this);
You could pass it as an argument instead.
bobsCar(this);
function bobsCar(domNode) {
$(domNode).toggle();
}
You should probably just use the function as the event handler in the first place though.
$('p').click(bobsCar);
You cannot directly use this in called function. You must have to pass selected object as function argument.
function bobsCar(element) {
$(element).toggle();
}
$('p').click(function() {
bobsCar(this);
});
This inside the function no longer reefers tot he 'p' tag, you could pass it
function bobsCar(el) {
el.toggle();
}
$('p').click(function() {
bobsCar($(this));
});
In JavaScript the $(this) is a context-pointer. It gives you the top-most context that is placed on the stack.
function bobsCar(elm) { console.log(elm);
$(elm).parent().toggleClass(); }
$('p').click(function() { var $this=$(this); bobsCar($this); });
jsfiddle.net/q325d6zw
I want to call jquery function in side of java script. My code is:
<script type="text/javascript">
function calljs(){
getUserMail(usermMail);
}
$(function() {
function getUserMail(usermMail) {
***some code*****
}
});
</script>
I got error from browser console:
ReferenceError: getUserMail is not defined.
How to solve this problem?
As far as i understand, the method is not defined when the method is being called. So define it before it is getting called
<script type="text/javascript">
function getUserMail(usermMail) {
***some code*****
}
function calljs(){
getUserMail(usermMail);
}
$(function() {
//
});
</script>
hope it helps
If it is really compulsory to put the function with in the jquery's ready callback (which I don't think is compulsory) use the following way
<script type="text/javascript">
var getUserMail = null;
function calljs(){
if ( null !== getUserMail ) {
getUserMail(usermMail);
}
}
$(function() {
getUserMail = function (usermMail) {
***some code*****
}
});
</script>
You can simply do ,
$(document).ready(function(event) {
getUserMail(usermMail);
});
and define it like ,
function getUserMail(usermMail){
. . .
}
or using jquery ,
$(document).on('click', ".selector", function);
trigger a function on an event
getUserMail is not defined in a scope that is accessible to calljs. This is why you get the ReferenceError; in the context in which you tried to invoke getUserMail there was no function with that name available.
// At this point nothing is defined
function calljs(){
getUserMail(usermMail);
}
// now calljs is defined as a global and can be invoked from anywhere
$(function() { // this line is calling a function named $ (an alias for jQuery)
// and passing it an anonymous function as a parameter.
function getUserMail(usermMail) { // This function is being defined inside
// the scope of the anonymous function,
// it can be used anywhere inside the
// anonymous function but not outside it.
// ***some code*****
}
});
// we are now outside the scope of the anonymous function,
// getUserMail is no longer in our scope and can't be called from here.
The easiest and likely best solution for most situations would be to make sure that any functions that call each other are in the same scope.
From what I can tell you don't really need calljs, you were just trying to use it to poke a hole into the scope of the anonymous function where getUserMail is defined.
Instead you should probably get rid of calljs and move any code that is calling getUserMail inside the ready callback. If getUserMail needs to wait for the ready callback to be fired before you call it, any code that invokes it also should be inside the ready callback too. (Things like event handlers that call it should already be inside the ready callback anyway.)
If there is a reason that you can't move it into the ready callback, such as something in another .js file needs to be able to call it etc, your application might be too complicated to be realistically maintained as jQuery soup. It might be worth the effort to port it to a framework such as Ember or Angular.
Also so you know, there is no need to use the type attribute on your script tags. JavaScript is the only language that has wide support in the browser and all browsers default to using JavaScript for script tags.
What follows is my Javascript document, that runs in $(document).ready(). The Javascript is loaded from the footer of my site. For the purposes of simplification, I've put [...] in place of irrelevant code.
// When the document is ready, run the display scripts
$(document).ready(function() {
// Define the frame height functions
function getDocHeight(doc) {
[...]
}
document.domain = 'mysite.com';
function resizeIframe() {setIframeHeight('date-price-book');}
function setIframeHeight(ifrm) {
[...]
}
function AutoResize() {
resizeIframe();
resizeIframe();
setTimeout("AutoResize()", 500);
}
AutoResize();
[... more Javascript code...]
When I run the page, I get the error: Uncaught ReferenceError: AutoResize() is not defined.
I can stop this error from occurring by commenting out the line AutoResize(); (final line in my example code above). But why is this error being thrown? Surely the AutoResize() function has just been defined in the lines immediately above it?
Thanks for your help!
setTimeout("AutoResize()", 500);
When the setTimeout above is executed, it evalutayes the string in global scope. AutoResize() is hidden inside the closure so it is not found.
Assign a reference to the function by using the name.
setTimeout(AutoResize, 500);
other option is a closure
setTimeout(function() { AutoResize(); }, 500);
You would use the closure method if you want to send a parameter to the function.
Because you're defining AutoResize inside the $(document).ready(function () { ... } ); closure, it's not available globally (which is nice).
When you use a string instead of a function reference when calling setTimeout (which is bad), there is an assumption that the function call that the string will resolve to is globally available (because setTimeout runs in window/global scope).
I'm not sure. It works when I try this part.
function AutoResize(){
console.log('test');
setTimeout('AutoResize()',1000);
}
AutoResize();
Maybe it's somewhere else that something is going wrong.
I am currently making use of Simon Willson's addLoadEvent function to add functions that I want to run after the load event. I ran into a problem wherein the the function I passed to the addLoadEvent function referenced a div that had not yet been loaded by the DOM and so my action (showing the div) did not do anything. When I changed to using the jQuery $(document).ready function, the div has been loaded by the DOM and I can execute actions with it (make it show up).
So, a couple questions. Why is my function being executed before the DOM has completed loaded using the above function? Is there a way to delay it? The other alternative that I can think of is passing in a function to a jquery equivalent:
function jqueryAddReadyEvent(myFunc)
{
$(document).ready(function()
{
//execute already existing functions
//add a new function to the ready event
myFunc();
}
}
When I try the above code, I get a javascript error "myFunc is not a function". Is there a way to generically pass in a function to the jquery ready function and have it execute? Equivalent to the following:
$(document).ready(function()
{
funcA();
}
$(document).ready(function()
{
funcB();
}
...//more of the same
Replaced with the following:
jQueryAddReadyEvent(funcA);
jQueryAddReadyEvent(funcB);
You can just do:
$(document).ready(myFunc);
to attach functions to the DOM ready event. Here's the fiddle: http://jsfiddle.net/padtE/
If you will require many functions to be added then I suggest you do the following:
Create an array that will old all the functions you want to call.
Add functions to that array as you please.
In the .ready(function() { ... }) call every function in that array.
You're set.
It looks correct to me. Most likely you are calling it with something not a function.
Btw you can shorten this to:
var jqueryAddReadyEvent = $(document).ready
or just use $(document).ready() directly for the same effect, as it specifically does what you want to do, run functions after the load, and is actually shorter.
$(document).ready(funcA);
$(document).ready(funcB);
function jqueryAddReadyEvent(myFunc) {
$(myFunc);
}
jqueryAddReadyEvent(function() {
alert('hello world');
});
Demo: http://jsfiddle.net/AlienWebguy/UzMLE/
Not sure if I am being totally wrong here but I want to do something like this:
Have an external js page (on an external server)
Include the page - OK that is easy etc...
Have a Jquery function on the external page - well actually many functions
Call those functions directly onto the page.
All a bit like this:
External js page:
$(document).ready(function() {
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_1() {
$('#test_2').load('page_2.php');
}
});
Then on the actual page just call:
<script type="script/javascript">
testit();
</script>
<div id="test"></div>
Am I wrong or should that not work?
You dont need to define the functions within the ready function, but you have to call it within the ready function.
$(document).ready(function() {
testit();
});
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_2() {
$('#test_2').load('page_2.php');
}
Otherwise testit() will be called before the document is loaded. And at that moment the function doesn't even exist yet in your example.
Your functions are local to the scope of the anonymous function passed as the argument to $(document).ready(). Here's a simple example showing the behaviour you're seeing:
(function() {
function foo() {
alert("It shouldn't alert this...");
}
})();
foo();
To fix it, simply move your function declarations outside of the ready function:
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_2() {
$('#test_2').load('page_2.php');
}
And use the ready function (shorthand $(function() { ... })) in your main js file:
$(function() {
testit_1();
});
I'm not sure if I'm understanding you wrongly, but will you load an external page of an external server? This is not possible on normal browser security settings. You cannot perform a succesful XMLHttpRequest for a document that resides on a different server. Nearly all browsers will block this and leave you with nothing. You would have to write a server-side proxy that fetches the document and serves it back to the client.
That should work fine. Just be sure to include the external JS file in your page and execute testit() inside another $.ready() call:
<script type="script/javascript" src="http://someurl.com/external.js"></script>
<script type="script/javascript">
$.ready( function() {
testit();
} );
</script>
<div id="test"></div>
The location of a JS file is irrelevant. Once it is loaded into your page, it is executed in the context of that page.