javascript load external file and continue processing - javascript

So I'm trying to avoid loading certain scripts until the user needs them but I keep ending up in the pattern of using an if...else and putting the call to the continue code in both places. In the code below you can see the two calls to the continueProcessing() method. Is there a better way of doing this?
if (typeof sessionList === "undefined" || typeof sessionList != "function") {
$.getScript('resources/sessionList.js', function() {
continueProcessing();
});
} else {
continueProcessing();
}
function continueProcessing() {
// do stuff
}

I haven't used getScript, but have faced a similar challenge with loading html templates. I've been using the deferred / promise approach. It would look like this for your case:
var jqXHR = {};
if (typeof sessionList === "undefined" || typeof sessionList != "function") {
jqXHR = $.getScript('resources/sessionList.js');
}
$.when(jqXHR).then(continueProcessing());
In the case where the script already exists, the jqXHR var will not be a deferred, so the "then" is executed immediately.
This is still a bit of code to type, but at least "continueProcessing" only appears once.

This looks like a good way of doing it to me.

So I played with the $.Deferred pattern/code and I came up with this. It's not as terse but I think it's a cleaner way of doing it. Looks like I have a lot of code to refactor...
var dfd = $.Deferred();
if ( typeof sessionList === "undefined" || typeof sessionList != "function" ) {
$.getScript('resources/sessionList.js', function(){
dfd.resolve();
});
}
dfd.done(function() {
continueProcessing();
});

Related

Set JavaScript variable to check definition later

How can you set a var to something you want to later check if it's defined or not?
Example: To check if jQuery is not defined, you'd do this:
if (typeof(jQuery) === 'undefined') {
}
But what if I want to do something like this (this obviously doesn't work):
var toCheckLater = jQuery; // This fails.
// Some time later..
if (typeof(toCheckLater) === 'undefined') {
}
What I'm trying to do is dynamically load scripts from an array, but I want to set ahead of time the variable whose definition I'll check for later. And I'd like to avoid a big block of ifs or switch statement. Meaning I'm hoping to find a solution a bit more elegant than:
switch (scriptName) {
case 'jQuery':
if (typeof(jQuery) === 'undefined') {
}
break;
case 'someOtherScriptName':
.
.
.
}
Any ideas?
Thanks in advance.
A function would do:
var toCheckLater = function() { return typeof jQuery == "undefined"; }
// later:
toCheckLater()
You might also use a fabric for such functions:
function getChecker(name) {
return function() {
return typeof window[name] == "undefined";
// alternative:
return name in window; // can be undefined, but the variable exists
};
}
var toCheckLater = getChecker("jQuery");
Use
if (typeof jQuery === "undefined")
to check for undefined.
I don't quite get what you're trying to achieve, but I think you could do something like this
var toCheckLater = typeof jQuery; //if, for example, jQuery is defined you'll get "function"
// Some time later..
if (toCheckLater === 'undefined') {
}
Simply do this:
var scriptName = 'jQuery';
if( !window.hasOwnProperty(scriptName) ){
//jQuery is undefined
}
var checker = function(scriptArray) {
for(var i in scriptArray)
this[i] = i?i:loadScript(i); // make your own loadScript function
}
checker({'jquery','anothercode'});
//access checker.jquery / checker.anothercode
You could use something like this. Create a 'class' that load all the scripts.
You have use the typeof Method
typeof(variable_name) will give you "string", "object", "undefined" or "number" depending on the variable
typeof(jQuery) == "undefined"
is the way to go.
Your array of scripts:
var scripts = ['script1', 'jQuery'];
After loading the scripts you can use the same array and loop through it.
for (var i = 0, n = scripts.length; i !== n; i++) {
if (!window.scripts[i]) {
// falsy
}
}
This assumes that the scripts array references a global variable that the script will expose when loaded.
However, if I understand what you're going for, a better method would be to register a callback for when the appropriate script element is loaded. See these questions for some examples: (1), (2)
Code like this is pretty standard:
function loadScriptAsync(src, callback) {
var script = document.createElement('script'),
place = document.getElementsByTagName('script')[0];
script.type = "text/javascript";
script.async = true;
script.src = src;
script.onload = script.onreadystatechange = function() {
callback();
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
};
place.parentNode.insertBefore(script, place);
}

Possible to Prototype ALL Objects

In javascript, is there a way to prototype all objects. A simple usecase would be, I have a function:
testFn(el) {
if(el.isElement()) {
//Do something
}
}
Here I would like to test if the object passed into the function is a DOM element. Normally I would use this function:
function isElement(el) {
if(typeof el == 'object' && 'nodeType' in el && el.nodeType === 1 && el.cloneNode) {
return true;
}
return false;
}
However, I find myself rewriting this code over and over again. It would be nice if I could simply prototype Object and have this function available on the fly for every object, whenever I might need it. Prototyping Object seems to give me errors though.
is there a way to prototype all objects
You can use prototype on Object:
Object.prototype.isElement = function () {
return typeof this == 'object' && 'nodeType' in this && this.nodeType === 1 && this.cloneNode
}

if Not undefined and indexOf ('foo') do something

So I'm trying to call where if not undefined and index is foo so I use:
if (typeof(getdata(js, 'box1')) != "undefined"
&& (getdata(js, 'box1')).indexOf('foo') >= 0) {
// Do something
}
This works fine but I dont want to call the getdata twice. Is there way to say if getdata is not undefined and the indexOf is foo then do something, without calling the getdata() function twice?
Alternative:
if (/foo/.test(getdata(js, "box1"))) {
// do something
}
While this allows you to get away with a single check, involving a regular expression for such a simple test could be frowned upon :)
You're better off using a local variable for storing the outcome of the function call:
var data = getdata(js, "box1");
if (data && data.indexOf("foo") ==! -1) {
// do something
}
Also note that typeof is an operator and not a function:
typeof something // instead of typeof(something)
Have you tried
var data = getdata(js, 'box1');
if(typeof(data) != 'undefined' && data.indexOf('foo') >= 0) {
}
You can read the indexOf of the value or an empty string if the value is undefined or null.
if ( (getdata(js, 'box1') || '').indexOf('foo') !=-1) {
// Do something
}
Hopefully your function will only return a string, undefined or null.

What's the simplest approach to check existence of deeply-nested object property in JavaScript? [duplicate]

This question already has answers here:
Test for existence of nested JavaScript object key
(64 answers)
Closed 8 years ago.
I have to check deeply-nested object property such as YAHOO.Foo.Bar.xyz.
The code I'm currently using is
if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
}
This works, but looks clumsy.
Is there any better way to check such deeply nested property?
If you expect YAHOO.Foo.Bar to be a valid object, but want to make your code bulletproof just in case it isn't, then it can be cleanest to just put a try catch around it and let one error handler catch any missing segment. Then, you can just use one if condition instead of four that will detect if the terminal property exists and a catch handler to catch things if the intermediate objects don't exist:
try {
if (YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// handle error here
}
or, depending upon how your code works, it might even just be this:
try {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}
I particularly use these when dealing with foreign input that is supposed to be of a particular format, but invalid input is a possibility that I want to catch and handle myself rather than just letting an exception propagate upwards.
In general, some javascript developers under-use try/catch. I find that I can sometimes replace 5-10 if statements checking input with a single try/catch around a larger function block and make the code a lot simpler and more readable at the same time. Obviously, when this is appropriate depends upon the particular code, but it's definitely worth considering.
FYI, if the usual operation is to not throw an exception with the try/catch, it can be a lot faster than a bunch of if statements too.
If you don't want to use the exception handler, you can create a function to test any arbitrary path for you:
function checkPath(base, path) {
var current = base;
var components = path.split(".");
for (var i = 0; i < components.length; i++) {
if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
return false;
}
current = current[components[i]];
}
return true;
}
Example usage:
var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
// a.b.c.d exists and can be safely accessed
}
var _ = {};
var x = ((YAHOO.Foo || _).Bar || _).xyz;
Consider this utility function:
function defined(ref, strNames) {
var name;
var arrNames = strNames.split('.');
while (name = arrNames.shift()) {
if (!ref.hasOwnProperty(name)) return false;
ref = ref[name];
}
return true;
}
Usage:
if (defined(YAHOO, 'Foo.Bar.xyz')) {
// operate on YAHOO.Foo.Bar.xyz
}
Live demo: http://jsfiddle.net/DWefK/5/
If you need to check the correctness of the path, rather than the existance of the "xyz" member on the "YAHOO.Foo.Bar" object, it will probably be easiest to wrap the call in a try catch:
var xyz;
try {
xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
// fail;
};
Alternately, you can do some string-kong-fu-magicTM:
function checkExists (key, obj) {
obj = obj || window;
key = key.split(".");
if (typeof obj !== "object") {
return false;
}
while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ;
return (!key.length && typeof obj !== "undefined");
}
The use as follows:
if (checkExists("YAHOO.Foo.Bar.xyz")) {
// Woo!
};
This problem is solved quite beautifully by coffeescript (which compiles down to javascript):
if YAHOO.Foo?.Bar?.xyz
// operate on YAHOO.Foo.Bar.xyz
use a try catch.
a={
b:{}
};
//a.b.c.d?true:false; Errors and stops the program.
try{
a.b.c.d;
}
catch(e){
console.log(e);//Log the error
console.log(a.b);//This will run
}
I actually voted to close the question as duplicate of javascript convert dotnotation string into objects.
However, I guess it's a different topic, but the answer there might still be helpful if you don't want to try-catch all the time.

How to check if function exists in JavaScript?

My code is
function getID( swfID ){
if(navigator.appName.indexOf("Microsoft") != -1){
me = window[swfID];
}else{
me = document[swfID];
}
}
function js_to_as( str ){
me.onChange(str);
}
However, sometimes my onChange does not load. Firebug errors with
me.onChange is not a function
I want to degrade gracefully because this is not the most important feature in my program. typeof gives the same error.
Any suggestions on how to make sure that it exists and then only execute onChange?
(None of the methods below except try catch one work)
Try something like this:
if (typeof me.onChange !== "undefined") {
// safe to use the function
}
or better yet (as per UpTheCreek upvoted comment)
if (typeof me.onChange === "function") {
// safe to use the function
}
I had this problem. if (obj && typeof obj === 'function') { ... } kept throwing a reference error if obj happened to be undefined, so in the end I did the following:
if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }
However, a colleague pointed out to me that checking if it's !== 'undefined' and then === 'function' is redundant, thus:
Simpler:
if (typeof obj === 'function') { ... }
Much cleaner and works great.
Modern JavaScript to the rescue!
me.onChange?.(str)
The Optional Chaining syntax (?.) solves this
in JavaScript since ES2020
in Typescript since version 3.7
In the example above, if a me.onChange property exists and is a function, it is called.
If no me.onChange property exists, nothing happens: the expression just returns undefined.
Note - if a me.onChange property exists but is not a function, a TypeError will be thrown just like when you call any non-function as a function in JavaScript. Optional Chaining doesn't do any magic to make this go away.
How about:
if('functionName' in Obj){
//code
}
e.g.
var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false
or as for your case:
if('onChange' in me){
//code
}
See MDN docs.
If you're using eval to convert a string to function, and you want to check if this eval'd method exists, you'll want to use typeof and your function string inside an eval:
var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"
Don't reverse this and try a typeof on eval. If you do a ReferenceError will be thrown:
var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined
Try typeof -- Look for 'undefined' to say it doesn't exist, 'function' for a function. JSFiddle for this code
function thisishere() {
return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);
Or as an if:
if (typeof thisishere === 'function') {
// function exists
}
Or with a return value, on a single line:
var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false
Didn't see this suggested:
me.onChange && me.onChange(str);
Basically if me.onChange is undefined (which it will be if it hasn't been initiated) then it won't execute the latter part. If me.onChange is a function, it will execute me.onChange(str).
You can even go further and do:
me && me.onChange && me.onChange(str);
in case me is async as well.
For me the easiest way :
function func_exists(fname)
{
return (typeof window[fname] === 'function');
}
Put double exclamation mark i.e !! before the function name that you want to check. If it exists, it will return true.
function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false
//Simple function that will tell if the function is defined or not
function is_function(func) {
return typeof window[func] !== 'undefined' && $.isFunction(window[func]);
}
//usage
if (is_function("myFunction") {
alert("myFunction defined");
} else {
alert("myFunction not defined");
}
function function_exists(function_name)
{
return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));
OR
function function_exists(func_name) {
// discuss at: http://phpjs.org/functions/function_exists/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Steve Clay
// improved by: Legaev Andrey
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: function_exists('isFinite');
// returns 1: true
if (typeof func_name === 'string') {
func_name = this.window[func_name];
}
return typeof func_name === 'function';
}
function js_to_as( str ){
if (me && me.onChange)
me.onChange(str);
}
I'll go 1 step further to make sure the property is indeed a function
function js_to_as( str ){
if (me && me.onChange && typeof me.onChange === 'function') {
me.onChange(str);
}
}
I like using this method:
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
Usage:
if ( isFunction(me.onChange) ) {
me.onChange(str); // call the function with params
}
I had the case where the name of the function varied according to a variable (var 'x' in this case) added to the functions name. This works:
if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); }
The Underscore.js library defines it in the isFunction method as this (which comments suggest may cater for some browser bugs)
typeof obj == 'function' || false
http://underscorejs.org/docs/underscore.html#section-143
If you're checking for a function that is a jQuery plugin, you need to use $.fn.myfunction
if (typeof $.fn.mask === 'function') {
$('.zip').mask('00000');
}
Here is a working and simple solution for checking existence of a function and triggering that function dynamically by another function;
Trigger function
function runDynamicFunction(functionname){
if (typeof window[functionname] == "function") { //check availability
window[functionname]("this is from the function it"); // run function and pass a parameter to it
}
}
and you can now generate the function dynamically maybe using php like this
function runThis_func(my_Parameter){
alert(my_Parameter +" triggerd");
}
now you can call the function using dynamically generated event
<?php
$name_frm_somware ="runThis_func";
echo "<input type='button' value='Button' onclick='runDynamicFunction(\"".$name_frm_somware."\");'>";
?>
the exact HTML code you need is
<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">
In a few words: catch the exception.
I am really surprised nobody answered or commented about Exception Catch on this post yet.
Detail: Here goes an example where I try to match a function which is prefixed by mask_ and suffixed by the form field "name". When JavaScript does not find the function, it should throw an ReferenceError which you can handle as you wish on the catch section.
function inputMask(input) {
try {
let maskedInput = eval("mask_"+input.name);
if(typeof maskedInput === "undefined")
return input.value;
else
return eval("mask_"+input.name)(input);
} catch(e) {
if (e instanceof ReferenceError) {
return input.value;
}
}
}
With no conditions
me.onChange=function(){};
function getID( swfID ){
if(navigator.appName.indexOf("Microsoft") != -1){
me = window[swfID];
}else{
me = document[swfID];
}
}
function js_to_as( str ){
me.onChange(str);
}
I would suspect that me is not getting correctly assigned onload.
Moving the get_ID call into the onclick event should take care of it.
Obviously you can further trap as previously mentioned:
function js_to_as( str) {
var me = get_ID('jsExample');
if (me && me.onChange) {
me.onChange(str);
}
}
I always check like this:
if(!myFunction){return false;}
just place it before any code that uses this function
This simple jQuery code should do the trick:
if (jQuery.isFunction(functionName)) {
functionName();
}
I have tried the accepted answer; however:
console.log(typeof me.onChange);
returns 'undefined'.
I've noticed that the specification states an event called 'onchange' instead of 'onChange' (notice the camelCase).
Changing the original accepted answer to the following worked for me:
if (typeof me.onchange === "function") {
// safe to use the function
}
I have also been looking for an elegant solution to this problem. After much reflection, I found this approach best.
const func = me.onChange || (str => {});
func(str);
I would suggest using:
function hasMethod(subject, methodName) {
return subject != null && typeof subject[methodName] == "function";
}
The first check subject != null filters out nullish values (null and undefined) which don't have any properties. Without this check subject[methodName] could throw an error:
TypeError: (undefined|null) has no properties
Checking for only a truthy value isn't enough, since 0 and "" are both falsy but do have properties.
After validating that subject is not nullish you can safely access the property and check if it matches typeof subject[methodName] == "function".
Applying this to your code you can now do:
if (hasMethod(me, "onChange")) {
me.onChange(str);
}
function sum(nb1,nb2){
return nb1+nb2;
}
try{
if(sum() != undefined){/*test if the function is defined before call it*/
sum(3,5); /*once the function is exist you can call it */
}
}catch(e){
console.log("function not defined");/*the function is not defined or does not exists*/
}
And then there is this...
( document.exitPointerLock || Function )();
Try this one:
Window.function_exists=function(function_name,scope){
//Setting default scope of none is provided
If(typeof scope === 'undefined') scope=window;
//Checking if function name is defined
If (typeof function_name === 'undefined') throw new
Error('You have to provide an valid function name!');
//The type container
var fn= (typeof scope[function_name]);
//Function type
If(fn === 'function') return true;
//Function object type
if(fn.indexOf('function')!== false) return true;
return false;
}
Be aware that I've write this with my cellphone
Might contain some uppercase issues and/or other corrections needed like for example functions name
If you want a function like PHP to check if the var is set:
Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}
To illustrate the preceding answers, here a quick JSFiddle snippet :
function test () {
console.log()
}
console.log(typeof test) // >> "function"
// implicit test, in javascript if an entity exist it returns implcitly true unless the element value is false as :
// var test = false
if(test){ console.log(true)}
else{console.log(false)}
// test by the typeof method
if( typeof test === "function"){ console.log(true)}
else{console.log(false)}
// confirm that the test is effective :
// - entity with false value
var test2 = false
if(test2){ console.log(true)}
else{console.log(false)}
// confirm that the test is effective :
// - typeof entity
if( typeof test ==="foo"){ console.log(true)}
else{console.log(false)}
/* Expected :
function
true
true
false
false
*/

Categories

Resources