As a result of publishing the series of post of the clock-in/out system, I had the need to write a function to import the data from a large XLS file to a Postgres database using the ORM (TypeORM).

This function was written quickly as a script without thinking too much about the quality of the code, but simply “work”. However, once the system is working and a test suite is available, it is a good idea to go through a constant refactoring to improve the code.

Next I will show different refactoring steps that I have applied to this function to improve the quality of the code. Therefore, the function that we are going to improve is shown first.

  • normalizedUID: this function is used to generate the name/uid (string) of each teacher.
import.ts

The main code would be as follows after the extraction of functions:

Before going on to address the next phase of refactoring, we will eliminate the variables that are understood using the domain of the problem, also the temporary variables will be removed.

In this moment, we see that we are making use of one of the most powerful features of JavaScript, functions as a parameter in the forEachmethods. But really, the forEach methods are only acting as syntactic sugar against the classical for of the imperative programming. Therefore, we will be modifying each forEach method by the most appropriate one according to the task that they perform.

The first forEach loop that we are going to address is the following:

This loop can be transformed into the method reduce because of what we want to get a single value (an array) after iterating through each of the days. In addition, the schedule variable can be omitted and the factorySchedule method can be invoked directly since the creation of this variable does not add semantic value in the code.

If we observe the function performed in the body of the method reduce, it is an if-else which can be transformed into a ternary operation that we can combine with the potential of immutability (another characteristic of functional programming) leaving the code as follows:

Another small step in the refactoring would be to omit the explicit invocation of return when using fat-arrow (lambda functions) of JavaScript, leaving the code as follows:

If we look at the code, the next natural step will be to replace the forEach method that includes the reduce by another method reduce. It may seem complicated the code that will generate since we are using the features of fat-arrow and spread operator (…) which if you never are used before can seem abstract (we will solve it by creating functions that allow you to decompose the task).

Therefore, the next step is to build small functions that perform the task that is done within each of the reduce. But we have a small problem, we need to pass extra parameters to each of the callbacks of the reduce methods. This problem is easily solved in JavaScript with different techniques such as overwriting the scope (this), using variables from a larger scope, or your own such as the bind, apply or call methods.

In our case, we are going to create several small functions that combined with the bind method will solve the problem of passing parameters in the callbacks. In this way, the resulting code until this moment would be the following:

The next step is to address the forEach method that encompasses the entire main method. The elimination of this method will allow us to eliminate the two variables that act as accumulators (users and schedulers). In such a way, that the method reduce will receive as an accumulator an array that contains two arrays (schedulers and users), which will be unstructured to be able to be concatenated easily in the method reduced.

After refactoring the code we find the following version:

In the same way as we did in the previous case, the method reduce receives a callback that is the one that performs the conversion to JSON, and finally we rename the content of the file to a variable called xls. So the partial result is the following:

Finally the result of the script after making these changes is shown below:

Summary

  1. Extract functions.

Originally published at www.carloscaballero.io on December 28, 2018.

Hi! My name is Carlos Caballero and I’m PhD. in Computer Science from Málaga, Spain. Teaching developers and degree/master computer science how to be experts!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store