What is the best way to check condition before run functions - javascript

I need to check some conditions before calling functions and those functions are calling from different js files like index.js or app.js.
What will be the best way to check that conditions before calling others? Think about you are doing something like authentication, if user is authenticated then call the function. I need to check that condition for 30 functions.
Instead of making changes on the functions I need to write one function/attribute/whatever and that needs to effect others.
file1.js:
function1
function2
function3
...
function30
file2.js:
file1.function1();
file3.js:
file1.function15();

To give an example of my suggestion in the comments, this is a simple way to wrap each function with an auth check without adding too much clutter to your calls.
// Some mock up of you existing code
var authenticated = true;
function thing1() { alert(1); }
function thing2() { alert(2); }
function thing3() { alert(3); }
// New code
function checkAuthAndRun(func) {
if (authenticated) {
func();
} else {
console.log("User is not allowed to do this");
}
}
// Calling your functions
checkAuthAndRun(thing1);
checkAuthAndRun(thing2);
checkAuthAndRun(thing3);
Example with parameters
// Some mock up of you existing code
var authenticated = true;
function thing1() {alert(1); }
function thing2(a) { alert(a); }
function thing3(a, b) { alert(a + b); }
// New code
function checkAuthAndRun(func) {
if (authenticated) {
// This line will need to have as many arguments[x] parameters as the function
// with the most parameters that you will call through this method
func(arguments[1], arguments[2]);
} else {
console.log("User is not allowed to do this");
}
}
// Calling your functions
checkAuthAndRun(thing1);
checkAuthAndRun(thing2, "Parameter 1");
checkAuthAndRun(thing3, "Parameter 1", "Parameter 2");

If I've understood your problem then I guess you don't want if-else or switch to clutter your code and you want a cleaner way to do this. What I would've done is, made a configuration file and executed it in the following way:
import {function1, function2, function3, function4 ...} from './functions';
const FUNCTIONS_TO_RUN = {
auth: () => {
function1();
function2();
...
},
noAuth: () => {
function3();
function4();
...
},
....
};
while calling them, I would just do as :
FUNCTIONS_TO_RUN[conditionType]();
This is not the exact solution but an idea how you can implement it in a cleaner way.
conditionType can be auth or noAuth in this case.

You may use && to short-circuit the statement.
Like, condition && fun() , fun() will be called only when conditon is true.
This is how && operator works in JS. if the first expression is wrong then it won't execute the rest of them otherwise it returns the value returned by the following expression(s), of course after executing them.
function auth(condition) {
return condition;
}
function isOdd(n) {
console.log(n," is odd ",n %2 == 0);
}
auth(false) && isOdd(3); //won't call
auth(false) && isOdd(4); //won't call
auth(true) && isOdd(5);
auth(true) && isOdd(6);

Related

how to conditionally include or exclude statements from function expression

i have 2 different javascript environments and want to create a library usable on both. to do that i want to use higher order functions to generate my functions, like so
try {
Maptool.chat.broadcast("")
var myFunc1 = genFunction1("env1");
}
catch(e){
if(e instanceof ReferenceError){
var myFunc1 = genFunction1("env2")
}
}
genFunction1 would return a function that i could call built from a function expression. there are only 2 ways i know to generate the function that is returned, it could be written similarly to the next code block with the if outside the inner function which would create a lot of code duplication as i would need to write everything in the function that is unchanged again.
function genFunction1(env){
if(env == "env1"){
return function () {return 3;}
}
else{
return function () {return 2;}
}
}
or with the if inside like the following code block
genFunction1(env){
return function (){
if(env=="env1"){
return 3;
}
return 2;
}
}
however if we use a object with a get property which logs when accessed we can see that the third code block calls a if for each call of myFunc1.
function genFunc1(obj){
return function (){
if(obj.env == "env2"){
console.log("3");
}
console.log("2");
}
}
const obj = {
get env() {
console.log("accessed property");
return "env2";
}
}
var myFunc1 = genFunc1(obj);
myFunc1();
myFunc1();
as previously said the earlier code block calls the get method once for each call of myFunc1(),but the environment won't change aside from the first time i check, is there any way to make the generated function not include a if and include the if only in the higher order function without duplicating code?
This is expected behavior as you are getting property from an object. Take a snapshot of the value before generating the function, like this.
function genFunc1(obj) {
var env = obj.env
return function() {
if (env == "env2") {
console.log("3");
}
console.log("2");
}
}

Break execution from function

Is possible to break execution program from function or I need to check boolean val returned?
Code
function check(something) {
if (!something) return;
// Else pass and program continuing
}
check(false); // I want to stop execution because function has returned
// Or I need to check value like if (!check(false)) return; ?
// I want easiest possible without re-check value of function..
alert("hello");
One way would be to through an Error, but otherwise you would need to use a boolean check, yes. I would recommend to use the boolean
function check(something) {
if (!something) throw "";
// Else pass and program continuing
}
check(false); // I want to stop execution because function has returned
// Or I need to check value like if (!check(false)) return; ?
// I want easiest possible without re-check value of function..
alert("hello");
Easiest...
(function(){
function check(something) {
if (!something) return false;
// Else pass and program continuing
}
if(!check(false)) return;
alert("hello");
});
(function(){ ... }); is called IIFE Immediately-invoked function expression.
Put your code in an IIFE, then you can use return
(function() {
function check(something) {
if (!something) {
return false;
} else {
return true;
}
}
if (!check(false)) {
return;
}
alert("hello");
});

Check if function returns true to execute another function

I have written a form validation using JS which ends with return(true);
function check() {
....validation code
return(true);
}
All I want is, need to check if check() function returns true, I want to execute another function.
Code I have tried is as follows:
if(check() === true) {
function() {
//Another function code
}
}
You should use return true; and your if statement doesn't need the === true comparison.
function check() {
//validation code
return true;
}
if(check()) {
//Another function code
}
JSFIDDLE
First of all, return is not a function, you can just do this:
return true;
Now, to only execute myFunction if check returns true, you can do this:
check() && myFunction()
This is shorthand for:
if(check()){
myFunction();
}
You don't need to compare the return value of check with true. It's already an boolean.
Now, instead of myFunction(), you can have any JavaScript code in that if statement. If you actually want to use, for example, myFunction, you have to make sure you've defined it somewhere, first:
function myFunction() {
// Do stuff...
}
You just need to modify your first code snippet. return is a keyword, what you are trying to do is to execute it as a function.
function check() {
....validation code
return true;
}
You'll need to change your 2nd snippet slightly, to execute the function too however... The simplest way is to wrap it as an anonymous function using curly braces:
if(check()) {
(function() {
//Another function code
})();
}
You're not calling the function in your affirmative clause, only declaring it. To call an anonymous function do this:
(function (){...})()
You could type
$this.myFunction=function(){
//code here
}
and to execute some code if a the myFunction function is true, you could use booleans
such as e.g.
if(//your function is true){
and so on

Make a function run once by redefining

I've found myself using this pattern recently to do initialization that should only ever run once:
function myInit() {
// do some initialization routines
myInit = function () {return;};
}
This way if I had two different methods which required something myInit did, it would ensure that it would only run once. See:
function optionA() { myInit(); doA(); }
function optionB() { myInit(); doB(); }
In the back of my head I feel like I'm missing something and I shouldn't be doing this. Is there any reasons why I shouldn't write code like this?
Is there any reasons why I shouldn't write code like this?
One reason is that the function will only work as you intend in the scope it was defined in. E.g. if you pass the function somewhere else, it won't be affected by your modifications and in the worst case would create an implicit global variable. E.g.
function myInit() {
// do some initialization routines
myInit = function () {return;};
}
function foo(init) {
init();
init();
}
foo(myInit);
The better approach is to encapsulate the whole logic:
var myInit = (function() {
var initialized = false;
return function() {
if (initialized) return;
initialized = true;
// do some initialization routines
};
}());
Now, no matter how, where and when you call myInit, it will do the initialization step only once.
May be you can do something like,
var myInitCalled = false; // Global declaration of flag variable
function myInit() {
// do some initialization routines
myInitCalled = true; // Setting the global variable as true if the method is executed
myInit = function () {return;};
}
Then in your methods, you can probably use:
function optionA()
{
if(!myInitCalled ) // Checking if first time this is called.
{myInit();}
doA();
}
function optionB()
{
if(!myInitCalled )
{myInit();}
doB();
}
This will ensure that myInit is called only once!!

Template method pattern with setTimeout in JavaScript

I have a close function that will close some instance. The class that includes the function allows derived classes to override close. Here, I want to make sure that close always calls dispose even in derived classes. I achieve this by the following.
function close() {
closeCore();
dispose();
}
function closeCore() {
// derived class can override this method.
}
This works fine, but I have one case where I want to perform CSS animation before I dispose the instance. This is what I do.
function close () {
instance.classList.add("fancy-animation-that-takes-800ms");
setTimeout(function () {
dispose();
},800);
}
But as soon as I do this, the template pattern I use cannot be applied. Is there a way to make sure the close function always call dispose in the second example?
You might have close expect an object be returned from closeCore which had parameters like these:
return {timeout: 800, callback: function () {/*....will execute after a timeout..*/}};
or:
return {callback: function () { /*...will be immediately executed...*/}};
or:
return function () { /*...will be immediately executed...*/};
...and then call their timeout for them (if any), and then after your timeout executed their callback, then call dispose for them.
The relevant part of your close code might look like:
function close() {
var ccObj = closeCore();
var ccIsObj = ccObj && typeof ccObj === 'object';
var callback = typeof ccObj === 'function' ? ccObj : (ccIsObj ? ccObj.callback : null);
if (ccIsObj && ccObj.timeout) {
if (!callback) {
throw 'You must implement a callback when supplying a timeout';
}
setTimeout(function () {
callback();
dispose();
}, ccObj.timeout);
}
else {
if (callback) {callback();}
dispose();
}
}
But if you want to allow the user to make arbitrary asynchronous calls of their own (such as Ajax), while you could instead allow the returning of a promise to which you added the dispose call, you wouldn't have a guarantee that the deriver would ensure the promise completed. You could automatically cancel the promise after a certain period of time, but you couldn't magically know when the deriving code was meant to finish unless again you abstracted this.

Categories

Resources