Uncaught ReferenceError:foobar is not defined (anonymous function) - javascript

I have this js file serving from some domain say foobar.com
at http://foobar.com/static/js/main.js:
$(document).ready(function() {
function foobar(bar){
$.ajax({
url: "/site/foo/",
data: {'foo':bar},
dataType: "jsonp",
crossdomain: !0,
success: function (data) {
alert(data);
},
error: function () {
}
})
}
});
On barfoo.com on some url, I have something like this:
<script src='http://foobar.com/static/js/main.js' type='text/javascript'></script>
<script type='text/javascript'>foobar('123456')</script>
When I hit that url : it says
Uncaught ReferenceError:foobar is not defined (anonymous function)
How to access function from other domains?

You've defined "foobar()" inside the "ready" handler. It's therefore a local variable in that function, and invisible outside it.
You could add this to the end of the "ready" handler:
window['foobar'] = foobar;
and then it'd be visible globally.
By the way this is something that can bite at jsfiddle because it (by default) will wrap code in a "load" handler. Thus, if you copy/paste from a JavaScript file included in the <head>, a function that would be global in that context ends up not global in the fiddle.

Your function is not visible globally as pointed out by Pointy. But you are also loading a script and calling a function defined by the ready() function. I guess it's possible ready() may not have been called when your script calls foobar() which would generate the same error. I would recommend you set a global value in your script and then use that variable in the ready() function.
Set the value in the script:
<script src='http://foobar.com/static/js/main.js' type='text/javascript'></script>
<script type='text/javascript'>var bar = '123456'</script>
Then you can use it in the ready() function.
$(document).ready(function() {
$.ajax({
url: "/site/foo/",
data: {'foo':bar},
dataType: "jsonp",
crossdomain: !0,
success: function (data) {
alert(data);
},
error: function () {
}
});
});
If you want to define a function so you can use it again you can call it in ready() but make sure you set the global variable bar to what you want.
window.foobar = function() {
$.ajax({
url: "/site/foo/",
data: {'foo':bar},
dataType: "jsonp",
crossdomain: !0,
success: function (data) {
alert(data);
},
error: function () {
}
});
}
$(document).ready(function() {
foobar();
// other stuff
});

Related

How to make addEventListener work for Javascript functions in a separate file?

I currently have document.addEventListener('DOMContentLoaded', functionName); which passes the following function as the parameter:
function functionName() {
$.ajax({
type: 'GET',
url: '/populatePage',
success: function(data) {
createPage(data);
}
})
}
Problem Description:
When the function above is in the same javascript file as the line document.addEventListener('DOMContentLoaded', functionName); the page loads properly.
But when the function is saved in a separate javascript file and then included in the file with the line above, the page does not load.
I'm probably missing something basic here, but can anyone please explain?
Make it global function.
It's not advisable but if you want quick solution then
window.functionName = function() {
$.ajax({
type: 'GET',
url: '/populatePage',
success: function(data) {
createPage(data);
}
})
}

How to work with JSONP to call back the function?

I am trying to communicate with a server using JSONP call back.
Here is my code
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
cache: false,
timeout: 40000,
crossDomain:true,
jsonp: "MyCallbackFunction",
});
});
function MyCallbackFunction(data)
{
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
The issue here is that I keep getting this message in the console
ReferenceError: MyCallbackFunction is not defined
I do have this defined as you can see in my code above
The server respond looks like this
MyCallbackFunction("{'URL': 'http:\/\/example.com:8106\/ghjgj3835396265336634646562363030303122226D616C686179656B22535353557DBE0C305645E2DE110AA1D7F8792E96A3'}");
how can I correct this issue?
EDITED
This is my code after Quentin Answer , this is my new code
$(function(){
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
timeout: 40000,
success: function(data){
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
});
});
});
Unless you have all of that code wrapped in another function, that should work.
Using a hardcoded function name is bad practise though.
Update:
$(function(){
You do have all that code wrapped in another function.
Remove this:
jsonp: "MyCallbackFunction",
Replace it with:
success: MyCallbackFunction
Or you could put an anonymous function expression there instead (as you have done in your edit)
Let jQuery generate a unique function name (which protects you from race conditions) and allow the server to use the callback query string argument to determine what function name to use.
MyCallbackFunction is in the same scope as the ajax call, so it will be available to the function (which can copy it to a suitably named global).
After you fix that, you have an additional problem:
MyCallbackFunction("{'URL':
Your response is JSON encoded in a JavaScript string, but you are trying to treat it as a JavaScript object.
Either:
Fix the server so it doesn't stringify the JSON or
Run the first argument through JSON.parse
crossDomain:true,
Remove that. It doesn't do anything here. (All it does is, when using XHR (which you aren't using) to the same origin (which you aren't targeting), suppress the custom headers that aren't typically allowed on a cross-origin request so that you can perform an HTTP redirect to a different origin).
cache: false,
That's the default for JSONP requests. Including it is pointless.
return false; //this is critical to stop the click event which will trigger a normal file download!
If you want to stop the click event, then you need to return false from the click event handler function (not the Ajax success handler).
You can't wait until the Ajax function has run and got a response before doing that. Ajax is asynchronous.

Scope variables in javascript,jquery

I am trying to access variable 'dimensions' in my ajax response but not able to get it. I dont want to make this variable global. Following is my code
$(document).ready(function(){
$('#submittext').click(function(){
var dimensions;
$.ajax({
type: "GET",
url: "bin/getcontentsize.php",
data: findContentsize,
success: function(response){
//want to access dimensions here to assign response and some calculation(but not able to access it)
}
});
//so i can use here
});
});
In this case you can access the dimensions variable from both the ajax call back and the code immediately after starting the ajax request. The variable is accessible in both of these contexts.
What is most likely causing the problem though is the timing. The success method will run asynchronously after the ajax request is completed. It's best to view this as executing later. However the code immediately after the $.ajax call will execute immediately. Hence you won't see any effects from the success handler on the dimensions variable when it runs.
If there is code you want to run with the value of dimensions as calculated by the success method you need to call that code from the success callback. For example
$('#submittext').click(function(){
var handleNewDimensions = function (dimensions) {
// Code that used to be after the $.ajax line
}
$.ajax({
type: "GET",
url: "bin/getcontentsize.php",
data: findContentsize,
success: function(response){
var dimensions = doTheCalculation(...);
// Call the code which needs to deal with the new dimensions
handleNewDimensions(dimensions);
}
});
Problem when you run it.
$(document).ready(function(){
$('#submittext').click(function(){
var dimensions="1";
$.ajax({
type: "GET",
url: "bin/getcontentsize.php",
data: findContentsize,
success: function(response){
dimensions = "2";
}
});
//!!!!Attention
alert(dimensions); // result is "1", not "2"
});
});
First, your code already ran. After that, your $.ajax starts to run.
Assign the dimensions variable the value, and test it again:
var dimensions="sample";
This should work:
$(document).ready(function(){
$('#submittext').click(function(){
var dimensions = 1;
$.ajax({
type: "GET",
url: "bin/getcontentsize.php",
data: findContentsize,
success: function(response){
alert(dimensions);
}
});
//so i can use here
});
});

$(this) selector issue jquery

i have this simple jquery function here.Clicking over a button i want to alert its own class before ajax and again upon succession..but the selector "$(this)" in the last situation is not working and the alert returns "undefined"..
why?
$(".button").live("click",function(){
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(this).attr('class')); //returns undefined
}
});
I would do it like this, store $(this) in a variable so you can use it throughout the function without having to perform a jQuery lookup every time, and you also will not have to depend on the scope to provide the correct element for $(this)
$(".button").live("click",function(){
var button = $(this);
alert(button.attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(button.attr('class')); //should also return "button"
}
});
});
wrapping this only once also is a performance enhancement
This will make it work:
$(".button").live("click", function() {
var button = this;
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) {
alert($(button).attr('class'));
}
});
});
You cannot use the this reference inside nested functions. The success function is a nested function and it has its own this value. If you need the reference to the button inside that nested function, you have to declare a local variable (like button).
function clickHandler() {
// this == element that was clicked
function ajaxHandler() {
// this != element that was clicked
}
}
Try adding var self = $(this); when you declare the function, and then use self instead of $(this)
So your code looks like this:
$(".button").live("click",function(){
var self = $(this);
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(self.attr('class')); //returns undefined
}
});
Lots of people have posted the solution for this so I won't post the code. Just wanted to mention the reason is because since the success method is a callback your context of $(this) isn't valid anymore. So you need to assign it to a variable and store it for your own use.
$(this) only exists when referencing an HTML object in the DOM. Since you've tried using in the success function of the AJAX call, $(this) has no reference. So for example, in the following code $(this) refers to the item to returned by the jQuery selector:
$('.button').each(function() {
alert($(this));
});
You will need to use a selector to return the item in global scope, and then pass this to the success function in the AJAX call:
var myButton = $('.button');
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) { alert(myButton.attr('class')); /* returns button */ }
});
Take a look at the context section here. Basically, what seems to be happening in your code is that the reference to this no longer applies. Makes sense, given that the context of the code has moved on while the AJAX callback is being handled asynchronously. Explicitly setting the context to a particular object in the .ajax() call will carry a reference to the context into the callback function.
You can either add a context: this property to the hash that is passed to the $.ajax call, that way the success handle will it's context set properly, or you can also do something like:
success: $.proxy(function(html) { // using $.proxy will bind the function scope to this
alert($(this).attr('class'));
}, this);
or, another technique I've seen:
$(".button").live("click",function(){
var self = this;
alert($(self).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(self).attr('class')); //returns undefined
}
});

how to pass a value to jQuery Ajax success-handler

Give the following Ajax call in jQuery:
{
.
.
.
,
getSomeData: function(args, myUrl, foo) {
$.ajax( {
type: "GET",
url: myUrl,
data: args,
async: true,
dataType: 'json',
success: myHandler
});
},
myHandler: function (data, textStatus, oHTTP, foo){ ... }
};
Can value foo be somehow appended to the arguments that are passed to success-handler myHandler? Is there any way to pass a value up to the server on the GET, and have that value come back to the client in a round-trip, reappearing in the success-handler's arguments list? I cannot change the structure of what is returned in data.
If you declare myHandler within the request, you can use a closure.
getSomeData: function(args, myUrl, foo) {
$.ajax( {
type: "GET",
url: myUrl,
data: args,
async: true,
dataType: 'json',
success: function (data, textStatus, oHTTP){ ... }
});
},
this way, foo will be available to you inside the success callback.
If you're $.ajax call is in a class and the success callback is passed a method of that class, it does not work.
EDIT: Here is the answer. Note that I am defining the function ajaxCall as a method in a class. I define this.before, this.error, and this.success as methods of ajaxCall because they can call methods from the superClass.
function main(url){
this.url = url;
this.ajaxCall = function(){
this.before = function(){
//Can call main class methods
};
this.error = function(){
//Can call main class methods
};
this.success = function(data){
//Can call main class methods
};
//This is how you pass class arguments into the success callback
var that = this;
$.ajax({
url: this.url,
type: 'GET',
dataType: 'json',
beforeSend: this.before(),
error: this.error(),
success: function(data){that.succes(data);}
});
//Run internally by calling this.ajaxCall() after it is defined
//this.ajaxCall();
}
//Or externally
var main = new main(SOME_URL);
main.ajaxCall();
#Unicron had the right answer but didn't give a good example. Check this out:
$( 'tr.onCall' ).on( 'click', function( event ) {
let pEvent = function() { return event; } // like a fly in amber...
$.ajax( {
...
success: function( data ) {
let x = pEvent(); // x now equals the event object of the on("click")
}
});
});
By declaring the pEvent function inside the anonymous function that fires on("click"), the event object is "frozen" (encapsulated) in its original context. Even when you call it in the different context of the ajax success function, it retains its original context.
More specific example: I'm going to open a modal dialog (styled Div) on click, but when the dialog is closed I want to return the focus to the element that was clicked to open it in the first place...
$( 'tr.onCall' ).on( 'click', function( event ) {
let rTarget = function() { return event.currentTarget; }
$.ajax( {
url: 'ajax_data.php',
...other settings...
success: function( data ) {
modal_dialog(
data,
{
returnTarget: rTarget(),
...other settings...
}
);
}
});
});
On success, it calls a custom function modal_dialog() (defined elsewhere), passing in an object containing various settings. The returnTarget setting contains the HTML ID attribute of the element that was clicked; so when I close the dialog I can run $(options.returnTarget).focus(); to return focus to that element.

Categories

Resources