collect.js: A Laravel-Like Syntax for JavaScript Arrays
Photo by Eran Menashri on Unsplash
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
If you're using Yarn, you can also choose to install it by running the following command:
yarn add collect.js
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>
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);
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);
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);
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]
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]
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]
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 }
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 },
// ]
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',
// },
// },
// ]
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'] },
// ]
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 usecontains
instead -
duplicatesStrict
- you can useduplicates
instead -
uniqueStrict
- you can useunique
instead -
whereStrict
- you can usewhere
instead -
whereInStrict
- you can usewhereIn
instead -
whereNotInStrict
- you can usewhereNotIn
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]
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]
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}
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}
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! 🚀
driesvints liked this article
Other articles you might like
How to add WebAuthn Passkeys To Backpack Admin Panel
Want to make your Laravel Backpack admin panel more secure with a unique login experience for your a...
Quickest way to setup PHP Environment (Laravel Herd + MySql)
Setting up a local development environment can be a time taking hassle—whether it's using Docker or...
Access Route Model-Bound Models with "#[RouteParameter]"
Introduction I've recently been using the new #[RouteParameter] attribute in Laravel, and I've been...
The Laravel portal for problem solving, knowledge sharing and community building.
The community