It looks like "$smth is not a function" is a very common problem with JavaScript, yet after looking through quite a few threads I still cannot understand what is causing it in my case.
I have a custom object, defined as:
function Scorm_API_12() { var Initialized = false; function LMSInitialize(param) { errorCode = "0"; if (param == "") { if (!Initialized) { Initialized = true; errorCode = "0"; return "true"; } else { errorCode = "101"; } } else { errorCode = "201"; } return "false"; } // some more functions, omitted. } var API = new Scorm_API_12();
Then in a different script I am trying to use this API in the following way:
var API = null; function ScormProcessInitialize(){ var result; API = getAPI(); if (API == null){ alert("ERROR - Could not establish a connection with the API."); return; } // and here the dreaded error pops up result = API.LMSInitialize(""); // more code, omitted initialized = true; }
The getAPI() stuff, looks like this:
var findAPITries = 0; function findAPI(win) { // Check to see if the window (win) contains the API // if the window (win) does not contain the API and // the window (win) has a parent window and the parent window // is not the same as the window (win) while ( (win.API == null) && (win.parent != null) && (win.parent != win) ) { // increment the number of findAPITries findAPITries++; // Note: 7 is an arbitrary number, but should be more than sufficient if (findAPITries > 7) { alert("Error finding API -- too deeply nested."); return null; } // set the variable that represents the window being // being searched to be the parent of the current window // then search for the API again win = win.parent; } return win.API; } function getAPI() { // start by looking for the API in the current window var theAPI = findAPI(window); // if the API is null (could not be found in the current window) // and the current window has an opener window if ( (theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined") ) { // try to find the API in the current window�s opener theAPI = findAPI(window.opener); } // if the API has not been found if (theAPI == null) { // Alert the user that the API Adapter could not be found alert("Unable to find an API adapter"); } return theAPI; }
Now, the API is probably found, because I do not get the "Unable to find..." message, the code proceeds to try to initialize it. But firebug tells me API.LMSInitialize is not a function
, and if I try to debug it with alert(Object.getOwnPropertyNames(API));
, it gives me a blank alert.
What am I missing?
Your LMSInitialize
function is declared inside Scorm_API_12
function. So it can be seen only in Scorm_API_12
function's scope.
If you want to use this function like API.LMSInitialize("")
, declare Scorm_API_12
function like this:
function Scorm_API_12() { var Initialized = false; this.LMSInitialize = function(param) { errorCode = "0"; if (param == "") { if (!Initialized) { Initialized = true; errorCode = "0"; return "true"; } else { errorCode = "101"; } } else { errorCode = "201"; } return "false"; } // some more functions, omitted. } var API = new Scorm_API_12();
For more generic advice on debugging this kind of problem MDN have a good article TypeError: "x" is not a function:
It was attempted to call a value like a function, but the value is not actually a function. Some code expects you to provide a function, but that didn't happen.
Maybe there is a typo in the function name? Maybe the object you are calling the method on does not have this function? For example, JavaScript objects have no map function, but JavaScript Array object do.
Basically the object (all functions in js are also objects) does not exist where you think it does. This could be for numerous reasons including(not an extensive list):
var x = function(){ var y = function() { alert('fired y'); } }; //the global scope can't access y because it is closed over in x and not exposed //y is not a function err triggered x.y();
var x = function(){ var y = function() { alert('fired y'); } }; //z is not a function error (as above) triggered x.z();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With