collect.js: A Laravel-Like Syntax for JavaScript Arrays

collect.js: A Laravel-Like Syntax for JavaScript Arrays

dev.to - Jan 23

Introduction

Collect.js is a JavaScript library by Daniel Eckermann that provides a convenient layer over the top of arrays. It offers a near-identical API to Laravel collections and makes working with arrays much easier (at least, in my opinion).

If you're anything like me, you're probably jumping between writing PHP code in Laravel and then building the frontend in JavaScript quite often when working on projects. In the past, when working with arrays in JavaScript, I've quite often thought to myself, "It'd be really handy if we just had XYZ method like in Laravel Collections". So, collect.js provides a really cool solution to this problems and bridges this gap by providing an API that is consistent with Laravel's Collections in PHP.

At the time of writing this article, collect.js has over 6.1k starts on GitHub and is being downloaded over 1.1 millions time a month!

In this article, we're going to take a look at collect.js, how to install it, and a few examples of common methods that you'll likely use in your own projects.

Installation

Install the Library

To get started with using collect.js, you can install it using NPM by running the following command in your project:

npm install collect.js --save
Enter fullscreen mode Exit fullscreen mode

If you're using Yarn, you can also choose to install it by running the following command:

yarn add collect.js
Enter fullscreen mode Exit fullscreen mode

Alternatively, if you'd rather just include the library via the CDN, you can add the following script tag to your HTML:

<script src="https://cdnjs.com/libraries/collect.js"></script>
Enter fullscreen mode Exit fullscreen mode

Include the Library

After you've installed the library, you'll then need to include it in your project so that you can use it. Let's take a look at a few examples from the library's documentation on how you can include it.

If you want to include it using require:

const collect = require('collect.js');

// You can then use it like so...

collect(products)
    .where('price', '>', 299);
Enter fullscreen mode Exit fullscreen mode

Or, if you'd prefer to use import:

import collect from 'collect.js';

// You can then use it like so...

collect(products)
    .where('price', '>', 299);
Enter fullscreen mode Exit fullscreen mode

Or, if you'd prefer to use the underlying class rather than using the collect() method:

import { Collection } from 'collect.js';

// You can then use it like so...

new Collection(products)
    .where('price', '>', 299);
Enter fullscreen mode Exit fullscreen mode

Examples

Now that you have collect.js included in your project and ready to go, let's take a look at some examples from the documentation of different methods available in the library that you'd likely use in your projects:

filter

The filter method filters the collection using the given callback and only keeps the items that pass the provided truth test.

Example:

const collection = collect([1, 2, 3, 4]);

const filtered = collection.filter((value, key) => value > 2);

// 'filtered' will now only include:

// [3, 4]
Enter fullscreen mode Exit fullscreen mode

reject

The reject method is the inverse of the filter method. It filters the collection using the given callback and removes any items that pass the provided truth test.

Example:

const collection = collect([1, 2, 3, 4]);

const filtered = collection.reject(value => value > 2);

// 'filtered' will now only include:

// [1, 2]
Enter fullscreen mode Exit fullscreen mode

map

The map method iterates through the items in the collection and passes them to the provided callback. The callback can be used to modify and then return the item. This method will then return a new collection with the modified items.

Example:

const collection = collect([1, 2, 3, 4, 5]);

const multiplied = collection.map(item => item * 2);

// 'multiplied' will now only include:

// [2, 4, 6, 8, 10]
Enter fullscreen mode Exit fullscreen mode

As mentioned in the documentation, it's worth noting that the map method returns an entirely new collection and doesn't modify the existing one. If you'd prefer to modify the existing collections, you can use the transform method instead.

firstWhere

The firstWhere method returns the first item in the collection that has the given key-value pair.

Example:

const collection = collect([
  { name: 'Regena', age: 12 },
  { name: 'Linda', age: 14 },
  { name: 'Diego', age: 23 },
  { name: 'Linda', age: 84 },
]);

const filtered = collection.firstWhere('name', 'Linda');

// 'filtered' will now only include:

// { name: 'Linda', age: 14 }
Enter fullscreen mode Exit fullscreen mode

sortBy

The sortBy method allows you to sort a collection using several different approaches.

Firstly, you can sort a collection using the name of the field like so:

const collection = collect([
  { name: 'Desk', price: 200 },
  { name: 'Chair', price: 100 },
  { name: 'Bookcase', price: 150 },
]);

const sorted = collection.sortBy('price');

// 'sorted' will now be:

// [
//   { name: 'Chair', price: 100 },
//   { name: 'Bookcase', price: 150 },
//   { name: 'Desk', price: 200 },
// ]
Enter fullscreen mode Exit fullscreen mode

You can use also dot notation to sort the collection using a nested value like so:

const collection = collect([
  {
    name: 'Desk',
    price: 200,
    manufacturer: {
      name: 'IKEA',
    },
  },
  {
    name: 'Chair',
    price: 100,
    manufacturer: {
      name: 'Herman Miller',
    },
  },
  {
    name: 'Bookcase',
    price: 150,
    manufacturer: {
      name: 'IKEA',
    },
  },
]);

const sorted = collection.sortBy('manufacturer.name');

// 'sorted' will now be:

// [
//   {
//     name: 'Chair',
//     price: 100,
//     manufacturer: {
//       name: 'Herman Miller',
//     },
//   },
//   {
//     name: 'Desk',
//     price: 200,
//     manufacturer: {
//       name: 'IKEA',
//     },
//   },
//   {
//     name: 'Bookcase',
//     price: 150,
//     manufacturer: {
//       name: 'IKEA',
//     },
//   },
// ]
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can also pass your own custom callback that should be used to sort the items like so:

const collection = collect([
  { name: 'Desk', colors: ['Black', 'Mahogany'] },
  { name: 'Chair', colors: ['Black'] },
  { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
]);

const sorted = collection.sortBy((product, key) => product.colors.length);

// 'sorted' will now be:

// [
//   { name: 'Chair', colors: ['Black'] },
//   { name: 'Desk', colors: ['Black', 'Mahogany'] },
//   { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
// ]
Enter fullscreen mode Exit fullscreen mode

To see a full list of available methods, you can check out the documentation at https://collect.js.org.

Differences Between Laravel Collections and collect.js

Although collect.js provides a similar API to Laravel Collections (in PHP), there are some differences to be aware of that might catch you out.

Laravel performs "loose comparisons" by default when working with items in Collections, and provides several methods that you can use for "strict" type checking. However, in collect.js, these extra "strict" type checking methods aren't implemented. Instead, all the methods (apart from the where method) in collect.js perform strict checks by default.

The following methods aren't implemented in collect.js:

  • containsStrict - you can use contains instead
  • duplicatesStrict - you can use duplicates instead
  • uniqueStrict - you can use unique instead
  • whereStrict - you can use where instead
  • whereInStrict - you can use whereIn instead
  • whereNotInStrict - you can use whereNotIn instead

Let's take a look at an example of how to perform a strict comparison using the where method. Let's imagine that we want to use the where method in a Laravel Collection:

$users = [
    ['name' => 'Ash', 'is_verified' => false],
    ['name' => 'Daniel', 'is_verified' => true],
    ['name' => 'Taylor', 'is_verified' => 'true'],
    ['name' => 'Jeffrey', 'is_verified' => 1],
];

$filtered = collect($items)->where('is_verified', true);

// $filtered would now contain the following items:

// ['name' => 'Daniel', 'is_verified' => true]
// ['name' => 'Taylor', 'is_verified' => 'true']
// ['name' => 'Jeffrey', 'is_verified' => 1]
Enter fullscreen mode Exit fullscreen mode

As you can see, three of the items are kept because true is strictly equal to true and loosely equal to "true" and 1.

If we wanted to perform a strict comparison, we could use the whereStrict method like so:

$users = [
    ['name' => 'Ash', 'is_verified' => false],
    ['name' => 'Daniel', 'is_verified' => true],
    ['name' => 'Taylor', 'is_verified' => 'true'],
    ['name' => 'Jeffrey', 'is_verified' => 1],
];

$filtered = collect($items)->whereStrict('is_verified', true);

// $filtered would now contain the following item:

// ['name' => 'Daniel', 'is_verified' => true]
Enter fullscreen mode Exit fullscreen mode

As you can see, we're only left with a single item because only strict comparisons were used.

If we wanted to use where in collect.js, we could write something like this:

const items = [
    {name: 'Ash', is_verified: false},
    {name: 'Daniel', is_verified: true},
    {name: 'Taylor', is_verified: 'true'},
    {name: 'Jeffrey', is_verified: 1},
];

const filtered = collect(items).where('is_verified', true);

// 'filtered' would now contain the following items:

// {name: 'Daniel', is_verified: true}
// {name: 'Taylor', is_verified: 'true'}
// {name: 'Jeffrey', is_verified: 1}
Enter fullscreen mode Exit fullscreen mode

If we wanted to perform a strict comparison (similar to the Collection's whereStrict method), then we could use the where method like so:

const items = [
    {name: 'Ash', is_verified: false},
    {name: 'Daniel', is_verified: true},
    {name: 'Taylor', is_verified: 'true'},
    {name: 'Jeffrey', is_verified: 1},
];

const filtered = collect(items).where('is_verified', '===', true);

// 'filtered' would now contain the following items:

// {name: 'Daniel', is_verified: true}
Enter fullscreen mode Exit fullscreen mode

As you can see in the example above, we've passed a === to the method as the second parameter, and this will be used as the operator when comparing filtering items.

Conclusion

Hopefully, this post should have given you a brief look at how you can use collect.js to use a Laravel-like syntax when handling arrays in JavaScript.

If you enjoyed reading this post, I'd love to hear about it. Likewise, if you have any feedback to improve the future ones, I'd also love to hear that too.

You might also be interested in checking out my 220+ page ebook "Battle Ready Laravel" which covers similar topics in more depth.

If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter.

Keep on building awesome stuff! 🚀

MORE ARTICLES