Test for undefined function in Javascript - javascript

So Safari keeps yelling at me for one specific error.
I'm trying to use Google Maps API and call map.getCenter();. However sometimes, this happens before the map has been fully loaded.
So instead in my function I test for an undefined call like this:
if (map.getCenter() != undefined)
But that still errors out because I guess it doesn't even like making the call just to test the if the result is undefined or not?
Can I get some help here?
Thanks!

I actually prefer something along these lines.
if(typeof myfunc == 'function') {
myfunc();
}
Just because something isn't undefined doesn't make it a function.

if (typeof map !== 'undefined' && map.getCenter) {
// code for both map and map.getCenter exists
} else {
// if they dont exist
}
This is the right way to check for existence of a function.. Calling the function to test its existence will result in an error.
UPDATE: Snippet updated.

if (typeof map.getCenter !== 'undefined')
Won't throw an error.
So, better yet, if (typeof map.getCenter === 'function') map.getCenter();

Technically you should be testing if map is undefined, not map.getCenter(). You can't call a function on an undefined reference.
However, Google's own tutorial suggests that you invoke your JavaScript that accesses the API in a body.onload handler, so that you do not attempt to reference anything until all of the remote .js files are loaded - are you doing this? This would solve the problem permanently, rather than failing cleanly when your JavaScript executes prior to loading the API.

I have been in the habit recently of using the typeof operator to test for things and types. It returns the type as a string which I think avoids some response type confusion.
if( typeof map.getCenter != 'undefined') ...
I'm not sure if it's more correct, but I find good results with this process.

You should be testing whether map is undefined. In your current check your are still trying to execute the function call.

Assuming that map.getCenter() is always a function, it's sufficient to just use this check:
if (map.getCenter) {
var x = map.getCenter();
}

The worked solution for me is try and catch,
const stopPropagation = (e) => {
try {
e.stopPropagation();
} catch (err) {
console.log("error with stopPropagation: " + err.error);
}
}
const triggerClick = (e) => {
stopPropagation(e);
};

Related

Conditional passing of a default parameter in Javascript

I'm coming up against 'window is undefined' errors while using React and Gatsby, so I want to conditionally pass a default value to my function parameter:
function useEventListener(element = window) {
I only want the function to be able to run if 'window' exists, and wrapping the contents of useEventListener inside an if statement isn't enough to avoid the error.
I was wondering if there is some way of doing it something like:
const windowDefined = () => typeof window !== "undefined";
function useEventListener(windowDefined ? element = window : element) {
can't you do the same inside the function, check it the parameter passed is undefined or not and return empty if it is?
function useEventListener( element) {
if(element){
return something
}
else{
return null
}
}
or wrap the whole function itself in a if condition and by default parameter it means it will work only if you don't pass a value,
please give more context for the question and usecase also
You could use a guard clause for this. If you just want the function to be prevented from running if window exists, the code would look like this:
function useEventListener() {
if (!window) return null
//function code here
}

How to avoid uncaught reference error

I have a common function for many pages as below
function (){
resetForm();
$ajax call
{
// some code //
}
}
now if i have not written the resetForm() fn in correspoding js, its giving the uncaught reference error as it should give and also my code followed after than line is not executed.
The js files where i have written resetForm fn() is working fine, but others are not.
The solution i have now is writing a blank resetForm function in other pages. Any other way ?
thanks for the help
You can check with typeof
if (typeof resetForm === 'function') {
resetForm()
}
// carry on.
This checks to see if you have a function called resetForm available and, if you do, executes it.
you can check it it exists (globally) and only than call it by:
window.resetForm && resetForm();
Here's a few obvious options:
Write a blank function like you did.
typeof resetForm === 'function' && resetForm();
Make sure to load only code that is relevant to the current page by better modularizing your code.
just check if resetForm is defined:
if (resetForm) {
resetForm();
}
I know it's not jquery-tagged question, but consider using jquery's onReady handler, it is executed when all javascript is loaded.
//main.js
$(function(){
resetForm();
});
//functions.js
function resetForm() { .. }
It will call resetForm properly event if resetForm is in separate js and loaded after main.js is loaded.

Javascript "this" pointer in Method Invocation Pattern not pointing to object

I am attempting to use the method invocation pattern in Javascript. I declare a function as an object member.
According to Javascript: The Good Parts, this should result in the this pointer referencing the enclosing object. When I've tried this before, this has been the case.
In the sample of code below, the this pointer reference by the single console.log statement is pointing to the function, not the object. I've double-checked my code and I honestly don't know what's going on.
I could use another pair of eyes on this. Is there something really obvious that I'm missing here, or am I expecting the wrong behavior? Thank you.
EDIT: I had a mistake in my code that I posted (it's been in flux); the keyword inside the anonymous function should be that, not this. Fixed.
DOUBLE EDIT: I've added the rest of my code within the module. I'm trying to write a commonJS module (in accordance with the gameJS library that I'm using) and although I'm not sure where that would be the problem, I'm wondering if it is. Does this change anything?
var gamejs = require('gamejs');
var system = require('app/system');
var input = {
eval_keys: function () {
console.log(this); // This should be the outer object, but shows the function!
var that = this;
gamejs.event.get().forEach(function (event) {
if (event.type === gamejs.event.KEY_DOWN) {
for (var key in that.keyconfig) {
if (that.keyconfig.hasOwnProperty(key)) {
if (event.key === gamejs.event[key]) {
that.keyconfig.key = true;
}
}
}
system.log("KEYDOWN", event.key);
}
if (event.type === gamejs.event.KEY_UP) {
for (var key in that.keyconfig) {
if (that.keyconfig.hasOwnProperty(key)) {
if (event.key === gamejs.event[key]) {
that.keyconfig.key = false;
}
}
}
system.log("KEYUP", event.key);
}
return keyconfig;
});
},
eval_mouse: function () {
/* in progress
else if (event.type === gamejs.event.MOUSE_MOTION) {
// if mouse is over display surface
if (display.rect.collidePoint(event.pos)) {
system.log("mousemove", testcoords);
testcoords = event.pos;
}
}
*/
},
keyconfig: {
K_UP: false,
K_LEFT: false,
K_RIGHT: false,
K_DOWN: false
}
};
exports.eval_keys = input.eval_keys;
Output from Chrome's dev console:
Object {eval_keys: function}
eval_keys: function () {
arguments: null
caller: null
length: 0
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
__proto__: Object
It looks like it does work to me, by calling input.eval_keys() after the object is declared.
Also the output you show in the console looks to me to be the output you want -- i.e., the outer object Object {eval_keys: function} containing the method.
The problem seems more to be that you should be seeing the other methods you declared in there, like this:
Object {eval_keys: function, eval_mouse: function, keyconfig: Object}
eval_keys: function () {
eval_mouse: function () {
keyconfig: Object
__proto__: Object
So, as far as I can tell, your question should be "why aren't these other methods showing up within my object in the console?" But I don't what else you are doing with the code that might account for that nor how and when you're invoking the relevant method.
Hope this helps.
It would work if you didn't use an anonymous function with that forEach loop, the this keyword has a different value inside there. You can pass it in a the second parameter:
gamejs.event.get().forEach(function (event) {
// this now refers to the outer this
}, this);
Alternatively you can use your that variable which refers to the outer this value as well.
Well, I figured out what was causing the this pointer to only show an object with one function - it was this line:
exports.eval_keys = input.eval_keys;
On a whim, I decided to add exports.keyconfig = input.keyconfig and it appeared in the console as part of the object.
It looks like the exports keyword does something with the this pointer when it's referenced, even if the this pointer is inside the module in question. I'm not exactly sure how that worked, but it did.
I'm running into more problems, but at the moment, the immediate issue has been resolved. I'll have to do some more reading on this.

Launching Script based on Eval Figure

$(".app-launch").on("click", function () {
var appId = this.id;
// Check if Function is running.
if (typeof eval('$' + appId).start == 'undefined') {
eval('$' + appId).start();
}
}
The eval just causes it to come back and say $XXXXXX is not defined and kills the java-script execution. Is there anyway to prevent it from killing the execution and continuing? This function is either launching the application or loading the javascript first and then launching the application, so this check is there to determine if the javascript has already been loaded.
Try this
eval('$("' + appId + '"')
First, stop using eval. If you want dynamically namable variables, use an object.
Then you can just test the type of the object before you try to access its start property.
var objects = {};
var appId = "thing";
objects[appId] = { start: foo; }
if (
typeof objects[appId] !== 'undefined' &&
typeof objects[appId].start === 'function'
) {
objects[appId]();
}
If you are trying to retrieve a global variable, just use the associative array syntax window['$'+appId]
Also, the reason your code is breaking is because you are checking if the start method is defined, whereas it is $XXXXXX that does not exist. Check if $XXXXXX exists before referencing the method. Also, you are calling the method if it is not defined, which makes no sense.
Also eval.
Here is a jsfiddle that shows what is wrong. Here is a fixed version.

How can I check a JavaScript function is loaded or exists in page before calling it?

Can anyone can give me a JavaScript code snippet by which I can detect if a JavaScript function is loaded in my aspx web page or exists before calling it?
Thanks
This will check if your function is defined.
if (typeof functionName === 'function') {
alert('loaded');
}
See it.
You could explicitly check that it's a function before calling it.
if (typeof(functionName) == "function")
functionName();
What do you mean by loaded?
In general you should use something like the onload event to make sure all your scripts have been loaded before you call them. In case you just want to whether a function has been declared or not you can use the typeof operator:
// Check the type of "myRandomFunction"
// Note: typeof is the only way you can use undeclared variables without raising an exception
if (typeof myRandomFunction === 'function') {
myRandomFunction()
}

Categories

Resources