Method Chaining with Lodash

As we, ASP.NET developers, transition from server side programming to client side programming, we are trying to find tools that help us to continue coding as usual. We welcome modern JavaScript that makes it possible to think in objects similarly to C#, and TypeScript that allows us to utilize strong typing.
When writing business application, we are routinely processing and displaying data. In ASP.NET (server side), we had a great tool called LINQ (Language Integrated Query). Using the LINQ fluent syntax with chaining made our code more compact and easier to read.
Lodash library is one of the best free open source utility libraries that allows us to do the same on the client side. Lodash works great with Node.js. We are using it in an Angular 2 application. It can handle robust data manipulations with ease. To read more about the library, explore the methods see the Lodash documentation. You can try the methods in RunKit and access the source code on GitHub as well.
I particularly like method chaining, which is similarly to LINQ, transforms the code naturally readable.
In the following example, I will show how I solve a data transformation task per requirements using Lodash library.

The Task

From the following garden inventory, generate a single sentence to list the live favorites. Limit the favorites to one per color. List the items by alpha order by color, and for each color, display the first item’s alias in the alphabetic order. Write the statement to the console with the following structure: “My favorites: ”
Example output: My favorites: green bean,white lilac

Data

[{category:'veggie', alias: 'tomato', color: 'red', isFavorite: true},
 {category:'veggie', alias: 'pepper', color: 'yellow', isFavorite: true},
 {category:'flower', alias: 'zinnia', color: 'red', isFavorite: true},
 {category:'flower', alias: 'tulip', color: 'yellow', isFavorite: false},
 {category:'pet', alias: 'dog', color: 'tri-color', isFavorite: true},
 {category:'pet', alias: 'cat', color: 'black', isFavorite: true},
 {category:'tool', alias: 'pruning knife', color: 'black', isFavorite: false},
 {category:'tool', alias: 'planter', color: 'red', isFavorite: true}]

Analysis

First, let us analyze the requirements to determine the steps we need to take.

  1. List live favorites. That means, we need to include all objects where isFavorite = true.
  2. Exclude all items that are not living thing. Looking at the data, we can see that category = tools should be removed from the data set.
  3. Limit the items to one per color. The easiest thing is to group them by color.
  4. Alphabetize the color groups and the items in them.
  5. Take the first item from each group.
  6. Create a string that shows the <item.color   item.alias> from each item left, separated by commas.
  7. Write the sentence to the console.

Implementation

The following screenshot shows the initial state of the task in RunKit. RunKit is an online code runner environment, the same that Lodash documentation uses for the code samples. The Lodash version of this example is 4.17.4. As you can see from the screenshot, RunKit is running on node.js. To use Lodash, you need to add the library as shown in line 1.

Code to implement the steps

Now that we have the steps, it is easy to write the code. The Lodash array/collection methods have an easy to remember signature. The first parameter is the array/collection the method is operating on. The second parameter is the instruction how to iterate through the array/collection. The instruction can be a function, named or anonymous, or an iteratee shorthand.

let favorites = _.filter(myGarden, 'isFavorite');
 let living = _.reject(favorites, ['category', 'tool']);
 let alpha = _.sortBy(living, ['color', 'alias']);
 let colorGroups = _.groupBy(alpha, 'color');
 let firstItemArray = _.map(colorGroups, function(group) {return group[0] ;});
 let transformedItems = _.map(firstItemArray, function(item){
 let text = _.join([item.color, item.alias], " ");
 return text;
 });
 console.log('My favorites: ' + transformedItems.toString());

The output:


As you can see, I used the _.filter method to include items that I want to keep and _.reject I wanted to remove. Then I sorted the result by color and alias order the data set for further processing. You might notice that I did that before I created the groups. The reason I could do that so easily that Lodash, according the comments in the source code, keeps the order of items.
Next, I group the items of the alphabetized data set. The _.groupBy method creates a dictionary type object, from which I use the _.map method to get the first items of each (already ordered) groups in an array format.
Now I am ready to generate the strings that describe the items. I am using the _.map method to iterate trough my array and get the item properties I need to display. I generate the comma-separated list using the _.join method.
At the last step I concatenate the static text with the string array which I flatten down with the toString() JavaScript method.
This solution does the work. What I do not like is that for every step I needed to come up with a new variable and pass it on to the next steps. Can we write this a little bit cleaner?
The Lodash library comes with a _.chain method. I can pass the initial dataset (array or collection) to it and fluently list the operations. The method names are the same, but I no longer need to pass the intermediate dataset around. There is no need for the underscores and the semicolons at each step. All I need to do is to resolve the result with the value() method.

Explicit chaining

let favorites = _.chain(myGarden)
 .filter('isFavorite')
 .reject(['category', 'tool'])
 .sortBy(['color', 'alias'])
 .groupBy('color')
 .map(function(group) {return group[0];})
 .map(function(item){
 let text = _.join([item.color, item.alias], " ");
 return text;
 })
 .value()
 .toString();
console.log('My favorites: ' + favorites);

This code is a lot cleaner, less cluttered, and easier to read and understand. This format uses a wrapper object, and similarly to LINQ, a deferred execution.
Lodash also offers an even simpler looking syntax, which uses a different wrapper.

Implicit chaining

let favorites = _(myGarden)
 .filter('isFavorite')
 .reject(['category', 'tool'])
 .sortBy(['color', 'alias'])
 .groupBy('color')
 .map(function(group) {return group[0];})
 .map(function(item){
 let text = _.join([item.color, item.alias], " ");
 return text;
 })
 .toString();
 console.log('My favorites: ' + favorites);

As you can see, in this syntax we no longer explicitly start and end the chain anymore. The code becomes simple and elegant, which makes code maintenance a lot easier. The syntax reminds me to the fluent LINQ syntax I used in C#. You might ask why you would use explicit chaining when a more elegant version exists. In my personal experience, at the time I am writing this, implicit chaining is a little bit fragile. Some more complex code that was happily use the explicit version, failed to run in the implicit wrapper.

Conclusion

In this example, I showed a data transformation task that uses Lodash library methods. I demonstrated the two different syntax available to chain the methods together to make the code much more readable.
You can access the code at https://runkit.com/lizascript/lodash-chain-example-solution.

Share on