Most effective method for streamlining conditional checks in JavaScript

To enhance the quality of my code and improve its readability, I have decided to implement a currying functions approach and create pure helper functions for repetitive code snippets. One issue I noticed was the frequent existence/type checks throughout my project in order to prevent potential errors like 'type of undefined'.

These checks typically look like:

if (param){
 action...
}

As a solution, I am considering developing a global helper function that takes two parameters; the 'param' to be checked and the 'action function' to execute if the check passes. The function will resemble this structure:

function isExist(param, action){
  if (param){
    action();
  }
}

However, this function may not be suited for all scenarios. How can I optimize it to work efficiently and universally across different cases? Moreover, I would appreciate insights on whether this approach is appropriate or if there is a superior method to achieve my objective here?

Example:

if (userInput){
  saveToDB(userInput);
}
if (valueFromDB){
  performSomeAction();
}
if (username && password){
  validate(username, password)
}

I aim to replace these separate checks at various points in my code with a single helper function, as shown below:

isExist( userInput, saveToDB(userInput) );
isExist( valueFromDB, performSomeAction );
isExist( (username && password), validate(username, password) );

This transformation condenses nine lines of code into just three, which aligns with my desired outcome.

Answer №1

When considering a suitable name for a particular function, one potential option could be

conditionalExecute(condition, codeToExecute)
. This concept may seem familiar, but it begs the question of whether it's just an elaborate way to reinvent the if-statement itself.

From my perspective, I fail to see the advantage of overcomplicating the logic behind the if-statement beyond its current form.

Update: In the realm of Javascript, a basic conditional expression like

if(someVariable){
  // do something
}

essentially translates to "If someVariable is truthy (where undefined falls short) then...."

If your aim is solely to verify existence (as in ensuring a variable isn't undefined), then perhaps it's more effective to have a clearly defined named function for that purpose.

In this scenario, concentrating on the exact checking process rather than the conditional aspect may prove beneficial since the if-statement already handles that. For instance:

function exists(x) {
  return x !== undefined; // or a similar condition
}
function isNotNull(x) {
  // implementation pending
}

This way, your code becomes more explicit and readable, allowing for potential combination of functions like so:

function neitherUndefinedNorNull(x){
   return exists(x) && isNotNull(x);
}

if(neitherUndefinedNorNull(X)){
  // regular code execution here
}

If the block inside the if-statement is repetitive, consider extracting it into a separate function as well.

function myRepeatedCode() {
   // perform necessary actions
}

function someAlternativeCondition(x){ 
  // evaluate conditions
}

if(neitherUndefinedNorNull ){
  myRepeatedCode();
} else if(someAlternativeCondition(x)) {
  myRepeatedCode();
}

// Alternatively, combine both conditions in a single if-statement
if(neitherUndefinedNorNull(x) || someAlternativeCondition(x)){
  myRepeatedCode();
}

Final note: To save characters, you could optimize by writing

// given short-circuiting behavior, myFunc1 and myFunc2 only execute
// when myCond1 and myCond2 are true (or truthy).
myCond1(x) && myFunc1(x)
myCond2(y) && myFunc2(y)

Answer №2

If you're searching for the ideal opportunity to utilize Maybe, then look no further:

const enumerable = true;

// data Maybe a = Nothing | Just a

const Maybe   = {};
const Nothing = Object.create(Maybe);
const Just    = value => Object.create(Maybe, {value: {enumerable, value}});

// instance Functor Maybe where

Nothing.map = _ => Nothing;
Maybe.map = function (fun) { return Just(fun(this.value)); };

// instance Applicative Maybe where

Maybe.of = Just;
Nothing.ap = _ => Nothing;
Maybe.ap = function (maybe) { return maybe.map(this.value); };

// instance Monad Maybe where

Nothing.chain = _ => Nothing;
Maybe.chain = function (kleisli) { return kleisli(this.value); };

Maybe follows the Fantasy Land Specification[1]. By incorporating Maybe into your code, you can craft functionalities like these:

// userInput :: Maybe Data
// saveToDB  :: Data -> Something
userInput.map(saveToDB); // :: Maybe Something

// valueFromDB       :: Maybe Data
// performSomeAction :: Data -> Maybe Something
valueFromDB.chain(performSomeAction); // :: Maybe Something

// username :: Maybe String
// password :: Maybe Password
// validate :: String -> Password -> Something
Maybe.of(validate).ap(username).ap(password); // :: Maybe Something

For those truly intrigued by functional programming, I recommend diving into Learn You A Haskell.


[1] While discussing the Fantasy Land Specification, there is a disagreement regarding flipping the arguments of ap.

Answer №3

How about this? It has the ability to process multiple parameters simultaneously.

function test(a,b,c)
{
    console.log("%s,%s,%s",a,b,c)
}

function check_and_run(param,action){
    var args = Array.prototype.slice.call(arguments);
    args.shift();
    args.shift();
    if(param)
        action.apply(this,args)  
}


check_and_run(1,test,1,2,3)  //this will invoke test(1,2,3)
check_and_run(0,test,1,2,3)  //this will do nothing

Answer №4

Maybe you can use a function like this:

function conditionFunction(condition, callbackFunction, defaultResult=undefined) {
  return (...args) => {
    if (condition(...args)) {
      return callbackFunction(...args);
    }
    return defaultResult;
  }
}

const add = conditionFunction(
   (...args) => args.every(num => typeof num === 'number'),
   (...args) => args.reduce((total, num) => total + num), 
   NaN);

add("1", "2"); //=> NaN
add(1, 2);     //=> 3

If you want to make sure that the first argument is not undefined:

const firstDefined = (value) => typeof value !== 'undefined';
const conditionalSomeFunction = conditionFunction(firstDefined, someFunction, "");

conditionalSomeFunction(); // ==> ""
conditionalSomeFunction("test"); // ==> whatever someFunction("test") returns

If your goal is to call a function only when all arguments are defined, you can do it simply like this:

function callIfDefined(func, ...args) {
  if (args.every(firstDefined)) {
    return func(...args);
  }
  return undefined;
}

callIfDefined(saveToDatabase.bind(this, userInput), userInput);
callIfDefined(performAction, valueFromDatabase);
callIfDefined(validate.bind(this, username, password), username, password);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Attaching a synchronous event listener to a form's submit button using JavaScript

I am currently tackling a security project in Javascript, a language I am not very familiar with, and I seem to be encountering some difficulties with EventListeners. Here is an excerpt of my code: function prevclick(evt) { evt.preventDefault(); document. ...

How to update the state of a component in the root layout from its child components in Next JS 13 with the app router?

I am in the process of upgrading a Next JS app project to utilize the App Router. Within the layout.js (the root layout), there is a Logo component that will be visible on all routes. Within the RootLayout, I am managing a state variable to modify the ap ...

$injector.modulerr problem

After spending a considerable amount of time analyzing every line of code, I can't seem to pinpoint any errors. Here is what I have: HTML: <body ng-app='myApp'> <div class="wrapper"> <nav> <ul ng-controller="pat ...

failure of svg spinning

I'm currently working with an SVG file and attempting to incorporate a spinning animation similar to loaders and spinners. However, I am facing an issue where the rotating radius is too large and I am struggling to control it effectively. CSS: .image ...

Incorporating the non-typescript npm package "pondjs" into Meteor applications using typescript files

Implementing the Pondjs library into my project seemed straightforward at first: meteor npm install --save pondjs However, I'm encountering difficulties when trying to integrate it with my Typescript files. The documentation suggests: In order ...

Combining properties from one array with another in typescript: A step-by-step guide

My goal is to iterate through an array and add specific properties to another array. Here is the initial array: const data = [ { "id":"001", "name":"John Doe", "city":"New York&quo ...

Wordpress tabs with dynamic content

I came across a code on webdeveloper.com by Mitya that had loading content tabs and needed the page to refresh after clicking the tab button. It worked perfectly fine outside of WordPress, but when I tried implementing it into my custom theme file, it didn ...

Python: passing a function as a parameter

Exploring the concept of passing functions as arguments to other functions has sparked a question in my mind: Is it possible to set a fixed value for some of the parameters when passing a function as an argument, in addition to their default value? For exa ...

Pass an item along with its superclass using express

Is there a way to send an object from an express server and then check the instanceof of that object on the receiving end? I am working on integration tests for express and need to verify the instanceof of the response body. Unfortunately, it seems like t ...

React.map does not retrieve the specific value

I am facing an issue with my list of items. I have implemented it using mui list, and I have also added a button for editing the list. However, when I click on an item, I am getting the value of the last item instead of the one I clicked on. Below is my f ...

Utilizing inter-process communication in Electron to establish a global variable from the renderer process

renderer.js ipcRenderer.sendSync('setGlobal', 'globalVarName').varInner.varInner2 = 'result'; main.js global.globalVarName = { varInner: { varInner2: '' }, iWontChange: ' ...

Encountering a TypeError while trying to import grapesjs into a nextjs project, specifically receiving the error: "Cannot read properties of null (reading 'querySelector')

I encountered an issue while trying to integrate grapesjs into a nextjs project. The error I received was TypeError: Cannot read properties of null (reading 'querySelector') It appears that grapesjs is looking for the "#gjs" container by its id ...

Using React.js to compute dates based on user-inputted dates

Today was dedicated to tackling the coding challenge of creating a function. I'm currently working on a react app using the PERN stack. The form I'm working on includes multiple date inputs, with two date columns and a total days column. My goal ...

"Transforming a query into a JSON array - a step-by-step

My query generates the following output: { key:1,label:"R. Bulan"} { key:2,label:"R. Bintang"} { key:3,label:"R. Akasia"} { key:4,label:"R. Guest Room"} This is my SQL query: select '{ '||'key:'||IDMEETINGROOM||''||',l ...

Bypass ajax request with the use of a returned promise

I've come across a scenario where I have a function within a class that is designed to return a promise for deleting an item. Here's what the function looks like: function Delete(){ // if(this.id == ""){ // return ?; // } ...

Encountering NaN in the DOM while attempting to interpolate values from an array using ngFor

I am working with Angular 2 and TypeScript, but I am encountering NaN in the option tag. In my app.component.ts file: export class AppComponent { rooms = { type: [ 'Study room', 'Hall', 'Sports hall', ...

Setting up eslint for your new react project---Would you like any further

I am currently working on a TypeScript-based React application. To start off, I used the following command to create my React app with TypeScript template: npx create-react-app test-app --template typescript It's worth noting that eslint comes pre-co ...

Displaying MySQL information on an EJS document including references to other tables

Check out the project on GitHub I am currently working on retrieving quiz answers from a MySQL database and displaying them in a form using EJS templating within a node.js/express application. However, I am facing challenges with correctly mapping answers ...

Exploring the POST method functionality in AJAX

I am having trouble creating a function that uses AJAX. When I try to send information using the POST method, the function does not work, but it works fine with the GET method. Here is the function: function ajaxFunction(page,metho ...

How would you go about creating a VueJS component that displays a table with a set number of columns and automatically distributes the cells within them?

Hey there! I'm currently working with a VueJS component that looks like this: <template> <div> <table> <tbody> <tr v-for="(item, index) in items" :key="index"> <t ...