Introduction

Lodash is a JavaScript library that makes it easy to work with arrays, numbers, objects, and strings by providing a variety of useful methods.

Thanks to this library, we do not have to waste time implementing the logic and algorithms, since we can simply use ready-made Lodash methods that have high performance, are well tested and documented.

Below there are some useful methods that are often in demand on frontend projects.

Functions for working with collections

The Lodash library has many methods for working with collections. Let’s consider some of them below.

_.map

The map method creates a new array that will consist of callback function results for each element of the array transferred by the first argument.

_.map([4, 8], item => ++item);
// => [5, 9]

The map method works with both arrays and objects.

_.map({ 'a': 4, 'b': 8 }, item => item * item);
// => [16, 64]

Also, if we work with an array of objects, the second argument can be the name of the property that should be put in the new array. In this case, map applies the property method to the second argument.

_.map([{ 'id': 4}, {'id': 8 }], 'id');
// => [4, 8]

_.map([{'first':[{ 'id': 4}]}], 'first[0].id');
// => [4]

_.includes

The includes method often checks whether the value is in the collection.

_.includes([1, 2, 3], 1);
// => true

_.includes([1, 2, 3], 1, 2);
// => false

It can also work with objects and strings.

_.includes({ 'a': 1, 'b': 2 }, 1);
// => true

_.includes('abcd', 'bc');
// => true

_.filter

You can use the filter method to filter an object. It creates a new array with elements for which the callback function returns true.

let users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false }
];

_.filter(users, item => item.active);
// => objects for ['barney']

The second argument can be an object with the exact values of properties by which filtering should be carried out. In this case, filter applies the matches method to the second argument.

_.filter(users, { 'age': 36, 'active': true });
// => objects for ['barney']

_.find

The find method is simple, but it is often necessary. It is iterated by the elements of the transferred array and returns the first element for which the callback function will return true.

let users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false }
];

_.find(users, item => item.age <= 40 );
// => objects for ['fred']

Just like the methods we have considered, the find method can accept a value object and a string of a specific property as the second argument.

If you need to search for an element in the collection from right to left, use the findLast method.

_.groupBy

It is a very interesting method that will allow to group array data based on the specified parameters. The area of application of this method is very large.

_.groupBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': [4.2], '6': [6.1, 6.3] }

_.groupBy(['one', 'two', 'three'], 'length');
// => { '3': ['one', 'two'], '5': ['three'] }

_.difference, _.differenceBy, _.intersection

The difference method creates a new array with elements that are unavailable in other transferred arrays. In other words, it compares two or more arrays and returns the difference between them.

_.difference([2, 1], [2, 3]);
// => [1]

The intersection method is very easy to understand, since it works inversely from the difference and creates an array of unique values that are included in all the specified arrays.

_.intersection([2, 1], [2, 3]);
// => [2]

The differenceBy method works similarly to the difference method, but it accepts additional parameters of the criterion by which the transferred arrays will be compared as the last argument.

_.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [1.2]

_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
// => [{ 'x': 2 }]

_.uniq, _.union

These two methods work in a similar way, but slightly differ in terms of independent application.

The _.uniq method creates an array that stores only the first occurrence of each element. In other words, the method excludes duplicate elements from the array.

_.uniq([2, 1, 2]);
// => [2, 1]

The union method works in the same way, except that it excludes duplicate elements from all the transferred arrays, and returns a new array created on this basis.

_.union([2], [1, 2]);
// => [2, 1]

Functions for working with objects

The Lodash library also provides excellent solutions for working with objects that will surely be needed in work.

_.pickBy

This method is used to work with objects in the same way as the map method is used to work with arrays. It creates a new object with enumerated properties of the transferred object, for which the callback function returns true.

let object = { 'a': 1, 'b': '2', 'c': 3 };

_.pickBy(object, _.isNumber);
// => { 'a': 1, 'c': 3 }

The isNumber method of the Lodash library checks for a number, see the documentation for more information.

_.assign, _.merge

Methods that combine and merge two or more objects are important and in demand.

The assign method assigns the enumerated properties of other transferred objects to the object transferred by the first argument, as shown in the example below.

let Foo = () => { this.a = 1; };
let Bar = () => { this.c = 3; };

Foo.prototype.b = 2;
Bar.prototype.d = 4;

_.assign({ 'a': 0 }, new Foo, new Bar);
// => { 'a': 1, 'c': 3 }

The merge method is similar to the assign method, but it performs deep recursive merging of intrinsic and ancestral enumerated properties of the transferred objects into an object.

let object = {'a': [{ 'b': 2 }, { 'd': 4 }]};
let other = {'a': [{ 'c': 3 }, { 'e': 5 }]};

_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }

The merge method, like the assign method, does not create a new object, but mutates the object transferred by the first argument.

_.clone, _.cloneDeep

These two methods create a copy of the transferred object and differ in some important features.

The clone method makes shallow copying of the object, which is clearly seen in the code example. It does not create copies of objects in the program memory, which are elements of the array.

let objects = [{ 'a': 1 }, { 'b': 2 }];

let shallow = _.clone(objects);
console.log(shallow[0] === objects[0]);
// => true

The cloneDeep method, on the contrary, performs deep recursive copying of the object, which can also be seen on the example below.

let objects = [{ 'a': 1 }, { 'b': 2 }];

let deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

Error handling functions

_.attempt and _.isError

If you work with the json data format on your project, you probably use the JSON.parse function, which turns a json string into a JavaScript object. But if the json string does not match the format, JSON.parse generates an error.

Of course, JavaScript provides methods for dealing with such errors, and to make the program secure, we will write the following code.

const parse = str => {
try {
return JSON.parse(str);
}

catch(e) {
return false;
}
};

parse('a'); // false
parse('{"name": "colin"}'); // Return {"name": "colin"}

There is nothing wrong with this code, but the Lodash library offers an even more concise solution.

The attempt method detects a JSON.parse error and returns an Error object instead.

const parseLodash = (str) => _.attempt(JSON.parse(str));

parseLodash('a'); // Return an error object
parseLodash('{"name": "colin"}'); // Return {"name": "colin"}

As you can see, the code has become even simpler and clearer. The program flow is not interrupted in case of a JSON.parse error, and the resulting Error object can be analyzed using the isError method.

const parseError = parseLodash('a'); // Return an error object

_.isError(parseError);
// => true

The area of application of the attempt method is very extensive, for example, when getting a DOM node on a html page. In this case, if the html element is not found, you will have to handle the error.

Function call chain

The functiontionality of chain data processing is a very flexible and powerful thing in Lodash. With the help of the call chain of various library methods, we can carry out more flexible work with data and solve complex tasks that go beyond the functionality of a particular library method.

_.chain

The chain method creates a so-called lodash shell instance, which can be used to apply several methods to data.

let characters = [
{ 'name': 'Barney', 'age': 36 },
{ 'name': 'Fred', 'age': 40 },
{ 'name': 'Pebbles', 'age': 1 }
];

let youngest = _.chain(characters)
.sortBy('age')// Sorting by 'age' property
.map(chr => chr.name + ' is ' + chr.age)// Properties values concatenation
.head()// Gets the first element
.value();// => Returns the value

console.log(youngest);
// => Pebbles is 1

The value method, which completes the chain, just makes the final chord and returns the finished processed value.

Conclusion

In the Lodash library there are many excellent useful methods for various tasks that have not been considered in the article. But I highly recommend studying the documentation to those frontend developers who have not yet used this library. This will noticeably accelerate the development of the frontend project logic, improve the quality and readability of the code and allow focusing on more important business tasks.