Home > Software engineering >  What can I do to reduce this code's complexity
What can I do to reduce this code's complexity

Time:12-06

I need to get the data using locationid or default in the below nodejs code, the code works, but how can I reduce the complexity? If day is selected, retrieve the data of the day loop by using the values given if locationid is null or not.

if (location_id == '') {
  if (filter_by === 'Day') {
    //12 hrs in a day
    graph_data = graph_data_of_day;
    query = {
      created_at: {
        gt: current_date,
      },
      ref: headerData ? .ref,
    };
  } else if (filter_by === 'Week') {
    // 7 days a week
    graph_data = graph_data_of_weeks;
    query = {
      created_at: {
        gte: startofweek_date,
        lte: endofweek_date,
      },
      ref: headerData ? .ref,
    };
  } else if (filter_by === 'Month') {
    // 4 weeks in a month
    graph_data = graph_data_of_months;
    query = {
      created_at: {
        gte: startOfMonth_date,
        lte: endOfMonth_date,
      },
      ref: headerData ? .ref,
    };
  } else if (filter_by === 'Year') {
    // 12 months_for_year in a year
    graph_data = graph_data_of_year;
    query = {
      created_at: {
        gte: startOfYear_date,
        lte: endOftheYear_date,
      },
      ref: headerData ? .ref,
    };
  } else if (filter_by === 'custom') {
    graph_data = [1, 2, 3, 4, 5, 7, 3, 12, 4, 2, 5, 6];
    query = {
      created_at: {
        gte: custom_start_date,
        lt: custom_end_date,
      },
    };
  }
} else {
  //if there is location id
  if (filter_by === 'Day') {
    //12 hrs in a day
    graph_data = graph_data_of_day;
    query = {
      created_at: {
        gt: current_date,
      },
      ref: headerData ? .ref,
      location_id: location_id,
    };
  } else if (filter_by === 'Week') {
    // 7 days a week
    graph_data = graph_data_of_weeks;
    query = {
      created_at: {
        gte: startofweek_date,
        lte: endofweek_date,
      },
      ref: headerData ? .ref,
      location_id: location_id,
    };
  } else if (filter_by === 'Month') {
    // 4 weeks in a month
    graph_data = graph_data_of_months;
    query = {
      created_at: {
        gte: startOfMonth_date,
        lte: endOfMonth_date,
      },
      ref: headerData ? .ref,
      location_id: location_id,
    };
  } else if (filter_by === 'Year') {
    // 12 months_for_year in a year
    graph_data = graph_data_of_year;
    query = {
      created_at: {
        gte: startOfYear_date,
        lte: endOftheYear_date,
      },
      ref: headerData ? .ref,
      location_id: location_id,
    };
  } else if (filter_by === 'custom') {
    graph_data = [1, 2, 3, 4, 5, 7, 3, 12, 4, 2, 5, 6];
    query = {
      created_at: {
        gte: custom_start_date,
        lt: custom_end_date,
      },
      ref: headerData ? .ref,
      location_id: location_id,
    };
  }
}

CodePudding user response:

We can immediately halve it using these two lines

let query = {};
if (location_id) query.location_id = location_id;

then we can have an object keyed by filter_by to make the complete code like this:

const filterData = { 
  "Day":    { graph_data: graph_data_of_day,    created_at: { gt: current_date }},
  "Week":   { graph_data: graph_data_of_weeks,  created_at: { gte: startOfWeek_date,  lte: endOfWeek_date    }},
  "Month":  { graph_data: graph_data_of_months, created_at: { gte: startOfMonth_date, lte: endOfMonth_date   }},
  "Year":   { graph_data: graph_data_of_year,   created_at: { gte: startOfYear_date,  lte: endOfYear_date }},
  "custom": { graph_data: graph_data_custom,    created_at: { gte: custom_start_date, lt: custom_end_date }}
};

let query = {};
if (location_id) query.location_id = location_id;
let { graph_data, created_at } = filterData[filter_by]; // spread is setting graph_data here.
query.created_at = created_at; // from the spread above
//    query.ref = headerData ? headerData : .ref; // not sure what .ref is.

console.log(graph_data,query)
<script>
const getDateString = date => date.toISOString().split("T")[0];
// testing: 
let filter_by="Month",                      // your data here  
location_id = "loc 1",                      // your data here 
graph_data_of_day    = ["day1","day2"],     // your data here 
graph_data_of_weeks  = ["week1","week2"],   // your data here 
graph_data_of_months = ["month1","month2"], // your data here 
graph_data_of_year   = ["year1","year2"],   // your data here 
graph_data_custom    = [1, 2, 3, 4, 5, 7, 3, 12, 4, 2, 5, 6], // your data here 
today = new Date(),
current_date = getDateString(today),
startOfWeek_date  = getDateString(new Date()), // I assume you have this code
endOfWeek_date    = getDateString(new Date()), // I assume you have this code
startOfMonth_date = getDateString(new Date(today.getFullYear(),today.getMonth(),1,15,0,0,0)),
endOfMonth_date   = getDateString(new Date(today.getFullYear(),today.getMonth() 1,0,15,0,0,0)),
startOfYear_date  = getDateString(new Date(today.getFullYear(),0,1,15,0,0,0)),
endOfYear_date    = getDateString(new Date(today.getFullYear() 1,0,0,15,0,0,0)),
custom_start_date = getDateString(new Date()), // your code here
custom_end_date   = getDateString(new Date()); // your code here

</script>

CodePudding user response:

To reduce the complexity of your code, you can use a single if statement to check the value of the filter_by variable, and then use a switch statement to handle the different possible values of filter_by. This will allow you to avoid repeating the same code multiple times, which will make your code more concise and easier to read.

Here is an example of how you could implement this:

if (filter_by === 'Day' || filter_by === 'Week' || filter_by === 'Month' || filter_by === 'Year' || filter_by === 'custom') {
  // Handle different values of "filter_by" using a switch statement
  switch (filter_by) {
    case 'Day':
      // 12 hrs in a day
      graph_data = graph_data_of_day;
      query = {
        created_at: {
          gt: current_date,
        },
        ref: headerData ? .ref,
        location_id: location_id,
      };
      break;
    case 'Week':
      // 7 days a week
      graph_data = graph_data_of_weeks;
      query = {
        created_at: {
          gte: startofweek_date,
          lte: endofweek_date,
        },
        ref: headerData ? .ref,
        location_id: location_id,
      };
      break;
    case 'Month':
      // 4 weeks in a month
      graph_data = graph_data_of_months;
      query = {
        created_at: {
          gte: startOfMonth_date,
          lte: endOfMonth_date,
        },
        ref: headerData ? .ref,
        location_id: location_id,
      };
      break;
    case 'Year':
      // 12 months_for_year in a year
      graph_data = graph_data_of_year;
      query = {
        created_at: {
          gte: startOfYear_date,
          lte: endOftheYear_date,
        },
        ref: headerData ? .ref,
        location_id: location_id,
      };
      break;
    case 'custom':
      graph_data = [1, 2, 3, 4, 5, 7, 3, 12, 4, 2, 5, 6];
      query = {
        created_at: {
          gte: custom_start_date,
          lt: custom_end_date,
        },
        ref: headerData ? .ref,
        location_id: location_id,
      };
      break;
  }
}

This code uses a single if statement to check if the filter_by variable is one of the expected values, and then a switch statement to handle the different cases. The location_id property is added to the query object in each case, so you don't need to repeat the same code twice, as you were doing in your original code.

CodePudding user response:

 graph_store = {
        'Day': graph_data_of_day,
        'Week': graph_data_of_weeks,
        'Month': graph_data_of_months,
        'Year': graph_data_of_year,
        'custom': [1, 2, 3, 4, 5, 7, 3, 12, 4, 2, 5, 6]
    };


buildQuery(location_id, graph_store, graphType, start, end){
   
    graph_data = graph_store[graphType];

    query = {
        created_at: {
            gt: start
        }
    };

if (graphType !== 'custom' && location_id !== '')Object.assign(query, {ref: headerData ? .ref})
if (graphType !== 'Day') Object.assign(query.created_at, {lte: end});
if (location_id !== '') Object.assign(query, {location_id: location_id});

return [graph_data,query];

}

When you break the filters down, there are only 3 actual difference's in your query object.

  1. Is it not a "Day", then add the "lte" property to "query.created_at".

  2. Does it have location, then add "location_id" property to "query".

  3. The "ref: headerData ? .ref" is a special case. Every query object has this property except "no location" and "custom".

Build the graph_store outside of the Querybuilder. There are too many operations within your block of code.

Return the query and data as an array of Objects.

  • Related