Simplify if statements by eliminating repetition

I have been tasked with refactoring the code below and I have already done so (check the image for reference). However, my supervisor is still not satisfied with the changes, LOL.

const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
    const fromDate = moment(input.requestDate)
      .subtract(retention, 'days')
      .toISOString();

    if (input.targetId && !input.userId) {
      // code for target id without user id
      let query = this.model
        .query('appTargetId')
        .eq(appTargetId)
        .where('createDate')
        .ge(fromDate)
        .where('status')
        .not()
        .eq(NotificationStatus.Delete);
      /* istanbul ignore next */
      if (input.subApplicationId) {
        query = query.filter('subApplicationId').eq(input.subApplicationId);
      }
      return query.exec();
    } else if (input.userId && !input.targetId) {
      // code for user id without target id
      return this.model
        .query('appUserId')
        .eq(appUserId)
        .where('createDate')
        .ge(fromDate)
        .where('status')
        .not()
        .eq(NotificationStatus.Delete)
        .exec();
    } else {
      // code for both user id and target id
      return this.model
        .query('appUserTargetId')
        .eq(appUserTargetId)
        .where('createDate')
        .ge(fromDate)
        .where('status')
        .not()
        .eq(NotificationStatus.Delete)
        .exec();
    }


https://i.sstatic.net/JFgJ7.png

Is there another way I could rewrite this code? I've spent countless hours trying to optimize it without much success. Any suggestions for improvement are highly appreciated.

Answer №1

In my opinion, this strikes a perfect balance between brevity and clarity.

When it comes to 1) pair of arrows, I find the index/indexstring variables to be quite cumbersome, so I opted to incorporate them into the if statement.

Regarding 2), I personally believe that the .where().not().eq() chains and similar structures are much easier to comprehend when condensed into a single line rather than being spread out.

As for 3), it can be streamlined into a single return statement.

const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
const fromDate = moment(input.requestDate)
   .subtract(retention, 'days').toISOString();

// Since the purpose of this function is query-building, it needs to be accessible throughout.
let query;

// Using single ifs enhances clarity
if (input.targetId) {
   if (input.userId) {
      query = this.model.query('appUserTargetId').eq(appUserTargetId);
   } else {
      query = this.model.query('appTargetId').eq(appTargetId);
   }
} else {
   query = this.model.query('appUserId').eq(appUserId);
}

// This segment is common
query = query
   .where('createDate').ge(fromDate)
   .where('status').not().eq(NotificationStatus.Delete);

// It's uncertain whether this is dependent on all 3 conditions or just subApplicationId would suffice
/* istanbul ignore next */
if (input.subApplicationId && input.targetId && !input.userId) {
   query = query.filter('subApplicationId').eq(input.subApplicationId);
}

// Perform the query
return query.exec();

Answer №2

Here's a more optimized version with simplified code structure:

const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);

const fromDate = moment(input.requestDate)
      .subtract(retention, 'days')
      .toISOString();
const index = (input.targetId ? (input.userId ? {"appUserTargetId" : appUserTargetId} : {"appTargetId": appTargetId}) : {"appUserId" : appUserId};

let query = this.model
        .query(Object.keys(index)[0])
        .eq(Object.values(index)[0])
        .where('createDate')
        .ge(fromDate)
        .where('status')
        .not()
        .eq(NotificationStatus.Delete);
if (input.subApplicationId) {
    query = query.filter('subApplicationId').eq(input.subApplicationId);
}

return query.exec();

If the reviewer prefers avoiding single line ternary operators, consider one of the following options:

(targetId && userId && {"appUserTargetId" : appUserTargetId}) || (targetId && {'appTargetId' : appTargetId}) || (userId && {'appUserId': appUserId})

[OR]

Implement Object Oriented Javascript (OOJS) by creating a base class and 3 extended classes, each corresponding to a specific if case. Here is a resource for learning the basics of OOJS:

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS

Answer №3

Give this a shot:

    const { targetAppId, userAppTargetId, userIdApp } = createIndexKeys(input);
    const fromDate = moment(input.requestDate)
      .subtract(retention, 'days')
      .toISOString();

    let indexString;
    let index;

    if (input.targetId && !input.userId) {
      // with target id but no user id
      indexString = 'targetAppId';
      index = targetAppId;
      /* istanbul ignore next */
    } else if (input.userId && !input.targetId) {
      // with user id but no target id
      indexString = 'userIdApp';
      index = userIdApp;
    } else {
      // user id and target id present
      indexString = 'userAppTargetId';
      index = userAppTargetId;
    }

    let query;
    if (input.subAppId) {
      query = query.filter('subAppId').eq(input.subAppId);
    } else {
      query = this.database
          .query(indexString)
          .eq(index)
          .where('creationDate')
          .ge(fromDate)
          .where('status')
          .not()
          .eq(NotificationStatus.Delete)
    }

    return query.exec(); 

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

Determine the specific button that was clicked within a React component

I have a challenge with dynamically generated material UI buttons. I am trying to identify which button was clicked by obtaining the value of the name attribute that I assigned to each button. Is there a way to accomplish this? In essence, I need to retrie ...

What is the best way to execute a .js file with a Mocha suite repeatedly within a loop?

I have a collection of .js test files and I am looking for a way to execute the tests in each file multiple times. Ideally, I would like to run them 5 or 10 times consecutively. Even if it's just one file at a time, but running it multiple times. I a ...

The function window.open when using the target '_blank' will launch a fresh browser window

I'm attempting to open a link in a new browser tab (not a new window). When I place a link on the page like this: <a href="#" onclick="window.open('http://www.google.com', '_blank');"> Click Here</a> when a user clic ...

Exploring Blob functionality in TypeScript?

I defined a global Blob object: declare global { interface Blob { prototype: Blob; new (name: string, url: string): Blob; } } It is functioning correctly in this code snippet: export const blobToFile = (blob: Blob) => { let file: File | n ...

Techniques for animating background image using jQuery

Hello there! I'm currently experimenting with animating a background image using jQuery. Despite following a tutorial, I haven't been successful in getting my test page to work as intended. The blue Facebook icon displays, but it doesn't ani ...

Live JSON sign-up feature on site

Is there a way to retrieve user email in real-time without using JSON? Currently, I am utilizing JSON for this purpose but it poses the risk of exposing emails that are stored in $resEmailsJson. Ideally, I would like to find a solution to hide all JSON $ ...

The closeOnClickOutside feature seems to be malfunctioning in the angular-2-dropdown-multiselect plugin

I'm currently using 2 angular-2-dropdown-multiselect dropdowns within a bootstarp mega div. The issue I'm facing is that when I click on the dropdown, it opens fine. However, when I click outside of the dropdown, it doesn't close as expected ...

Changing the structure of a webpage in real-time and inserting new elements into the document

I have a custom x-template filled with a survey element (including a text field and radio button). Upon loading the screen, the database sends a JSON object to the UI based on previously stored sections. This JSON object is then used to populate the survey ...

Confusion about the unwinding of the call stack in the Graph Depth-

Issue with function: hasPathDFSBroken Fix implemented in: hasPathDFS The updated version includes a forced parameter to address the issue, which I would prefer to avoid. I'm trying to comprehend why in the broken version, when the call stack unwinds ...

Select a random index and modify it until all unique options have been exhausted, then restart the process

My image gallery has 6 slots for images, and I have an array with a certain number of image objects: "src" : { "1x" : "/clients/Logo-1.png", "2x" : "/clients/<a href="/cdn-cg ...

Obtain the output of a single controller in a different controller within the Express framework

Seeking to invoke a function from one controller in another Controller1.js 2) Controller2.js Code within Controller1.js file: var Controller2= require('../controllers/Controller2.js'); exports.getlist = function (req, res, next) { Control ...

Learn how to properly implement cookies in a fetch request within Nextjs

Here is a code snippet to consider: Index.getInitialProps = async function({req}) { const res = await fetch("http://localhost/api/tiles"); const json = await res.json(); } If the /api/tiles endpoint requires access to the uid cookie from the user, t ...

Tips on Avoiding Initial Click Activation

I've been working on a JavaScript function that dynamically generates an iframe with a button that, when clicked, deletes the iframe itself. Here are the functions I've written: function createIframe (iframeName, width, height) { var ifram ...

Creating a switch statement that evaluates the id of $(this) element as a case

I have a menu bar with blocks inside a div. I am looking to create a jQuery script that changes the class of surrounding blocks in the menu when hovering over a specific one. My idea is to use a switch statement that checks the ID of $(this) and then modif ...

Potential issue of excessive memory usage in node.js when running an Express server with PM2

Currently, I am focusing on a specific aspect of a suite of services designed to work in conjunction with an app/platform. The particular area that requires assistance is related to a vanilla express server used to provide our client app (a react app). We ...

The email provided is invalid according to the response received from the Campaign Monitor API within a Meteor JS

I'm currently facing an issue with a project using Meteor. I'm attempting to add an email address to a subscriber list through the Campaign Monitor API. To do this, I'm utilizing a npm package called createsend-node, which acts as a wrapper ...

Can you explain the concept of a framework operating "on top of" node.js in a way that would be easy for a beginner to understand?

If someone is new to JavaScript, how would you explain the concept of "on top of node.js" in simple programming language? I am looking for a general explanation as well as specific reference to Express on top of node.js in the MEAN stack. Appreciate your ...

What causes my absolutely positioned element to disappear when using overflow-x: hidden?

I've been experimenting with the CSS property overflow-x: hidden on a container and noticed that it causes my element with position: absolute to disappear. To see this effect in action, check out this demo: https://codepen.io/Karina1703/pen/LYMzqEj ...

Encountering a non-constructor error while trying to import packages in React Typescript

I am currently working on a project that utilizes React with Typescript. While attempting to import a package, I encountered an error stating that the package lacks a constructor when I run the file. This issue seems to be prevalent in various packages, a ...

Customizing Material UI Components: Implementing the onChange Method

I've been working with the materia kit react template from creative-tim: However, I noticed that the customerInput component in this template lacks an onChange method. Does anyone have a solution for handling user inputs using this specific template? ...