Uncaught TypeError: Property ... is not a function - after page has loaded
I'm using a cross-domain Ajax request to an external API. Every so often it fails, with the console message:
Uncaught TypeError: Property 'photos' of object [object DOMWindow] is not a function
Looking at the JSON being returned, it is valid JSON, so it is not the fault of the external API.
I can't reproduce the error reliably: the only factor that seems to trigger the error is when I call the request quickly and repeatedly.
In this case I'm calling the Ajax request when the user moves a Google map (to add markers to the map), and it occurs if the user moves around too quickly.
Here are the relevant parts of my code:
// Code located inside an external JS file referenced inside the head
// Not wrapped inside do开发者_开发百科cument.ready - but all the code setting up
// the map (calling a function which calls a function which adds the
// tilesloaded listener) *is* inside document.ready
function addMarkers() {
var pm_url = "http://www.cyclestreets.net/api/photos.json?key=" + MY_KEY;
$.ajax({
url: pm_url,
crossDomain: true,
contentType: "application/json",
dataType: 'jsonp',
data: pmdata,
jsonpCallback: 'photos',
success: function(data) {
// TBA
},
error: function() {
alert("Sorry, error retrieving photos!");
}
});
}
google.maps.event.addListener(map, 'tilesloaded', function() {
addMarkers(map);
});
Having Googled a bit, the error Uncaught TypeError: Property 'photos' of object [object DOMWindow] is not a function
generally seems to occur when jQuery has not been loaded.
However, I don't see that this is relevant here, because the function is called from the map's tilesloaded event - and it doesn't generally fire the first time, it tends to fire after five or six rapid map resizes. So if it works once, the page surely can't have 'forgotten' about jQuery?
Thanks for your advice.
If you want to specify the name of the function that jQuery creates from your success
handler, but not actually define a separate function to use, you should use jsonp: 'photos'
instead of jsonpCallback: photos
. Currently it's using photos
in the URL which means it's calling photos({ ...data... })
when the JSONP response comes back, and that doesn't exist. Using the jsonp
option on $.ajax()
would create it. You have a few options here.
You can do this (in a global scope) either of these two ways:
function addMarkers() {
var pm_url = "http://www.cyclestreets.net/api/photos.json?key=" + MY_KEY;
$.ajax({
url: pm_url,
crossDomain: true,
contentType: "application/json",
dataType: 'jsonp',
data: pmdata,
jsonpCallback: 'photos',
error: function() {
alert("Sorry, error retrieving photos!");
}
});
}
function photos(data) {
// TBA
}
Or, what you intended I think:
function addMarkers() {
var pm_url = "http://www.cyclestreets.net/api/photos.json?key=" + MY_KEY;
$.ajax({
url: pm_url,
crossDomain: true,
contentType: "application/json",
dataType: 'jsonp',
data: pmdata,
jsonp: 'photos',
success: function(data) {
// TBA
},
error: function() {
alert("Sorry, error retrieving photos!");
}
});
}
....or just leave both off and let jQuery name the success
callback itself (this happens by default, based on a timestamp).
精彩评论