Testing the existence of a method - javascript

I'm trying to make some existing JS backwards compatible. I need to override a method if it does not exist, otherwise just return the existing method.
Here is the code I have so far:
this.grid.getDataSource = function(){
if (getDataSource == undefined)
return getStore();
else
return getDataSource();
}
However it keeps returning an error on the "if" line:
getDataSource is undefined
What is the best way of going about this?

This should work without throwing an error.
if (typeof getDataSource != "function")

you might need to wrap it in a typeof() function
this.grid.getDataSource = function(){
if (typeof getDataSource == undefined)
return getStore();
else return getDataSource();
}

this.grid.getDataSource = getDataSource || getStore;

Here is a nice resourse, which should answer to your question. It's a pretty simple function.
http://phpjs.org/functions/method_exists:471

Related

Function to check if variable is not undefined and not null

I'm looking for a way to do the following:
var test = 'I exist!';
var testNull = null;
var testUndefined;
function checkVar(varToCheck) {
return typeof varToCheck != 'undefined' && varToCheck != null;
}
console.log(checkVar(test)); // Logs true
console.log(checkVar(testNull)) // Logs false
console.log(checkVar(testUndefined)) // Logs false
console.log(checkVar(undefinedVar)) // Logs false
When it tries to execute the last line, instead of false, this throws an error: Uncaught ReferenceError: undefinedVar is not defined.
I know it can be done with:
if (typeof varToCheck != 'undefined' && varToCheck != null) {
alert('something happens!')
}
but it's becoming annoyingly repetitive to use long conditions in my project, once I have a lot of variables to check. Any ideas?
typeof is unnecesary. also, !== will check specifically for the type and not just falsy/truthy values.
function checkVar(varToCheck) {
return varToCheck !== undefined && varToCheck !== null;
}
undefinedVar is not a variable with an undefined value, it was never declared to begin with, and will throw an error if you try reference it.
However, object properties that weren't declared will not throw an error if you try reference them, and will compute to undefined.
What I was looking for was a secure way to access values of nested objects.
I ended up using a tiny lib called Typy, which provided exactly the functionality I needed.
I will leave Typy and some other alternatives I've found:
Typy
Lodash's _.get
get-value

check if localStorage.removeItem() was successful

If I remove an item using localStorage.removeItem("key"); is there any way I can check if the removal was successful or not? Something like a callback or promise?
Right now I am doing like this:
if(localStorage.getItem("key"))
localStorage.removeItem("key");
else
console.log("Error");
Is this the right way to do it or could this be done in a "better" way?
The removeItem() call does not return any indication of failure1 of any sort (excerpt taken from a recent editor's draft of the W3C web storage specification, with my emphasis):
The removeItem(key) method must cause the key/value pair with the given key to be removed from the list associated with the object, if it exists. If no item with that key exists, the method must do nothing.
Hence, the only way to tell if the key was an actual removal (as opposed to the "do nothing" action in the second sentence above) is to check it first.
You should almost certainly use explicit checking of the getItem() return value against null (with === of course) but that doesn't change the fact that you can't detect failure with removeItem() itself1.
Of course, if you're worried about peppering your code with these snippets, you're quite able to define a function to do the heavy lifting for you, something like:
function removeExistingItem(key) {
if (localStorage.getItem(key) === null)
return false;
localStorage.removeItem(key);
return true;
}
and then call it with the more succinct:
if (! removeExistingItem("key"))
console.log("Error");
1 This is based on "failure" being defined as the key not existing (as seems to be the definition you're using in the question). In reality, removeItem() cannot fail simply because it will do nothing in the case where the item does not exist (see inset above).
A more accurate check will be as below, else if the value of the key was ""(empty string) then it will fail
if (localStorage.getItem("key") !== null) {
localStorage.removeItem("key");
} else {
console.log("Error");
}
Storage.getItem() will return null if the key is not found
I ran into this same issue today [06-23-2019], and adjusted #paxdiablo's answer to add a few more fail-safes to the solution. I really hope my version helps someone else save the time and headache I went through:
/* Conditional Function supplements localStorage.removeItem(...) to return a [Boolean] 'success' or 'failure' value. [BEGIN] */
if (typeof removeLocalStorageItem !== 'function')
{
function removeLocalStorageItem(key)
{
if (typeof (Storage) !== 'undefined')
{
if (localStorage.getItem(key) === null)
{
return false;
};
localStorage.removeItem(key);
if (localStorage.getItem(key) === null)
{
return true;
}
else
{
return false;
};
}
else
{
return false;
};
};
};
/* Conditional Function supplements localStorage.removeItem(...) to return a [Boolean] 'success' or 'failure' value. [END] */

How do I verify if several attributes are in a JSON structure within JavaScript?

I am creating a module that takes in several complicated JSON files and would like some code to give the user feedback if certain elements are absent.
Below is the way I am doing it now, but I cannot help to think there must be a cleaner, less hacky way.
var _und = require("underscore");
//this function takes a list of required attributes and ensures they are present
var check_req_attr = function(config, req_attr, callback) {
var config_attr = Object.keys(config);
var absent_attr = _und.difference(req_attr, config_attr); //slightly hacky code that checks to ensure config has correct vars
if (absent_attr.length !== 0) {
throw Error("missing following attributes from config:" + absent_attr);
} else {
callback();
};
};
It just feels...dirty. If there is no real elegant way to do it, I would be open to critiques on my code. Thanks!
Parse the JSON to JS.
var data = JSON.parse(theJson);
Use something like:
function hasKey(obj, key) {
return typeof obj[key] !== 'undefined';
};
function hasKeys(obj, keys) {
for (var i = 1, len = keys.length; i < len; i++) {
if (!hasKey(obj, keys[i])) {
return false;
};
};
return true;
};
Now you can simply do:
if (hasKeys(data, ["firstKey", "secondKey", "thirdKey"]) {
console.log("valid");
};
This should be the way to do it, using every and has:
if (_und.every(req_attr, function(attr) {
return _und.has(config, attr);
}))
throw new Error();
In a native environment, you would just use the in operator:
req_attr.every(function(attr){ return attr in config; })
I think your solution is actually quite elegant! No need for an anonymous function, and the loop (which must happen at some point, obviously) neatly abstracted away with difference.
Two suggestions:
I'd give the function a synchronous signature. No callback argument. There can't be any reason to go async if you honor the function signature (i.e. basing your answer on config and req_attr only).
I'd change the function to return the missing properties (attributes is wrong term). You could also add a requireProperties function that uses this "check" function that would throw if a property was missing. This allows for different kind of uses.
Why don't you try with something like:
obj = JSON.parse(json);
and then check
if(obj.YourProperty == undefined){
//do something..
}
Hope i understood your question.. It should work with complicated JSON files too.. Good luck ;)
You could also use the in operator (requiredAttr in obj):
function objHasAllRequiredAttrs(obj, attrNames) {
return attrNames.reduce(function(memo, attrName) {
return memo && (attrName in obj);
}, true);
}
objHasAllRequiredAttrs({foo:1}, ['foo']); // => true
objHasAllRequiredAttrs({bar:1}, ['foo']); // => false

How to evaluate potentially undeclared variable's properties?

I have a variable that in some cases isn't declared, and I want to use it in a jQuery template. This is what I am trying to achieve, but it throws an *payment_method is not defined* exception:
{{if payment_method && (payment_method.id == $value.id)}}
// this throws an exception when payment_method is undeclared!
{{/if}}
This works:
{{if payment_method }}
{{if payment_method.id == $value.id}}
// nested works!
{{/if}}
{{/if}}
but I'm not too keen of a nested solution since I use it alot. I clearly understand why the first case throws the error, what I am looking for is a possible workaround for this without resorting to the second solution.
This issue probably boils down to problems in js to check properties for undeclared/undefined variables. This works:
if("undefined" !== typeof undefinedVariable) {
// this works just fine also for undeclared variables
}
but this doesn't:
if("undefined" !== typeof undefinedVariable.property) {
// this throws an exception
}
Any ideas?
When using an undefined/undeclared variable it doesn't throw any exceptions, but using it's properties does. This is where it gets a bit fuzzy though.
If you check for the existence of this undeclared variable by typeof, it evaluates to false (at least I think so, it does so when being the only condition...) and does not continue to check for further conditions. If you only check for it's existence by it's name, it evaluates to false, but the next condition gets evaluated none the less...
Anyhow, this does not throw any exception:
if(typeof undeclaredVariable !== "undefined" && typeof undeclaredVariable.property !== "undefined") {
// this works just fine
}
and neither does:
if(typeof undeclaredVariable !== "undefined" && undeclaredVariable.property) {
// this also works just fine but is shorter
}
but this does:
if (undeclaredVariable && undeclaredVariable.property) {
// the conditional clause does not stop at undeclaredVariable but also checks for undeclaredVariable.id where it throws an exception
}
Without understanding the true mechanisms of how conditions get evaluated, the answer to my question is (successfully tested):
{{if typeof payment_method !== "undefined" && payment_method && (payment_method.id == $value.id)}}
EDIT: Using an undefined/undeclared variable throws an exception in js, but it does not in jQuery tmpl.
js:
if (undeclaredVariable) {
// throws an exception
}
jQuery tmpl:
{{if undeclaredVariable}}
// evaluates to false, but does not throw an exception
{{/if}}
Here is what you need, working in best way.
try {
if (!! someVariable)
{
//its declared you can use it
}
else
{
//its not declared
}
}
catch (e) {
//its not declared
}
You can use the hasOwnProperty function to check for the existence of a property on an object.
See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/HasOwnProperty
The trouble in js is you need to check the property exists first before you can test anything against it, so it make condition a bit messier.
{{if payment_method && payment_method.id && (payment_method.id == $value.id)}}
var foo;
var bar = 'defined';
try{
if(someVariable === 'undefined') {
console.log('undefined'); //foo
}else{
console.log('declare && defined'); //bar
}
}catch (e){
console.log('undeclared'); //undeclaredVariable
}
{{if this.data.payment_method && this.data.payment_method.id == $value.id}}{{/if}}

Tell if a Javascript function is defined by looking at self[name] - is this a good way?

This is a follow up question to This Question.
I like (and understand) the solution there. However, in the code I am working in, another way to solve the same problem is used:
function exist(sFN) {
if(self[sFN]) return true;
return false;
}
It seems to work fine, although I don't understand how. Does it work? How? What are minuses of this approach? Should I switch to solution from the other question?
Try this:
function exist(sFN) {
return (typeof sFN == 'function');
}
Your condition is checking the existence of the "sFN" property in the "self" object. Anything that isn't null, undefined, 0, and "" will evaluate to true.
As others have said, you can use typeof, or instanceof to see if it's actually a function.
Looking at your linked example, you should read up on the difference between ==/!= and ===/!== in javascript. Short answer: ("" == null) is true, ("" === null) is false.
just use typeof.
typeof(foobar) // -> undefined
typeof(alert) // -> function
You can't, however, defined a function based on typeof, because you'd need to pass an identifier which might not exist. So if you define function isfun(sym) { return typeof(sym) }, and then tried calling isfun(inexistent), your code would throw.
The fun thing about typeof is that it's an operator, not a function. So you can use it to check a symbol that's not defined without throwing.
if you assume a function in the global scope (i.e., not within a closure), you can define a function to check it as follows:
function isfun(identifier) {
return typeof(window[identifier]) == 'function';
}
Here you pass an string for the identifier, so:
isfun('alert'); // -> true
isfun('foobar'); // -> false
closure?
Here's an example of a function defined within a closure. Here, the printed value would be false, which is wrong.
(function closure() {
function enclosed() {}
print(isfun('enclosed'))
})()
FYI: There is (or was) a nice pitfall for typeof.
FF2 returns 'function' for typeof(/pattern/).
FF3, IE7, and Chrome all return 'object' for the same code.
(I can't verify other browsers.)
Assuming everyone that used FF2 has upgraded, you're in the clear.
But, that's probably a far-fetched assumption.
You can't really wrap this in a method, but it's so simple there is really no need.
function bob()
{}
if( typeof bob == "function" )
alert( "bob exists" );
if( typeof dave != "function" )
alert( "dave doesn't" );
Object.prototype.toString.apply(value) === '[object Function]'
I read somewhere (here and here) that functions are properties of the window object, so you can do the following:
if (window.my_func_name) {
my_func_name('tester!');
}
or for popups:
if (window.opener.my_func_name) {
my_func_name('tester!');
}
A complete solution then:
function function_exists(func_name) {
var eval_string;
if (window.opener) {
eval_string = 'window.opener.' + func_name;
} else {
eval_string = 'window.' + func_name;
}
return eval(eval_string + ' ? true : false');
}

Categories