Support the ongoing development of Laravel.io →

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

23 Jan, 2023 7 min read

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 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]

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! 🚀

Last updated 3 weeks ago.

driesvints liked this article

1
Like this article? Let the author know and give them a clap!
ash-jc-allen (Ash Allen) I'm a freelance Laravel web developer from Preston, UK. I maintain the Ash Allen Design blog and get to work on loads of cool and exciting projects 🚀

Other articles you might like

November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.