DEV Community

Cover image for JavaScript 2024: Exciting Features You Can’t Miss
Jaimal Dullat
Jaimal Dullat

Posted on • Originally published at Medium

JavaScript 2024: Exciting Features You Can’t Miss

Object.groupBy()
Object.groupBy() is a shiny new static method introduced in ECMAScript 2024.

This handy method lets you group the elements of an iterable (like an array) into a new object.

The grouping is based on the values returned by a provided callback function. Sounds neat, right?

Let’s break it down a bit more.

Syntax

Here’s how you use it:

Object.groupBy(items, callbackFn);
Enter fullscreen mode Exit fullscreen mode

How Does It Work?

  1. items: This is your iterable, such as an array, that you want to group.

  2. callbackFn: This is a function that gets called for each element in the items iterable. It should return a value that can be turned into a string or symbol, which will be used as the key for the group in the resulting object.

Object.groupBy() calls callbackFn for each element in the items iterable and uses the returned values as keys in the resulting object. The resulting object has properties for each unique key returned by callbackFn, and each property value is an array containing all the elements from the original items iterable that had the same key.

A Practical Example

  • Let’s say you have an array of objects representing an inventory, and you want to group the items by their type property. Here’s how you can do it:
const inventory = [
    { name: "asparagus", type: "vegetables", quantity: 5 },
    { name: "bananas", type: "fruit", quantity: 0 },
    { name: "goat", type: "meat", quantity: 23 },
    { name: "cherries", type: "fruit", quantity: 5 },
    { name: "fish", type: "meat", quantity: 22 },
];

const result = Object.groupBy(inventory, ({ type }) => type);
Enter fullscreen mode Exit fullscreen mode
  • In this example, the callbackFn is an arrow function that simply returns the type property of each object. The resulting result object will look like this:
{
    fruit: [
        { name: "bananas", type: "fruit", quantity: 0 },
        { name: "cherries", type: "fruit", quantity: 5 }
    ],
    meat: [
        { name: "goat", type: "meat", quantity: 23 },
        { name: "fish", type: "meat", quantity: 22 }
    ],
    vegetables: [
        { name: 'asparagus', type: 'vegetables', quantity: 5 },
    ],
}
Enter fullscreen mode Exit fullscreen mode

Map.groupBy()

Map.groupBy() is a new static method introduced in ECMAScript 2024 that allows you to group elements of an iterable, just like Object.groupBy(), but with the added benefit of using a Map.

The Map structure provides some advantages, such as maintaining the order of insertion and allowing for more complex key types.

Syntax

Here’s how you can use Map.groupBy():

Map.groupBy(items, callbackFn);
Enter fullscreen mode Exit fullscreen mode

How Does It Work?

  1. items: This is your iterable (e.g., an array) that you want to group.

  2. callbackFn: This is a function that will be called for each element in the items iterable. It should return a value that will be used as the key for the group in the resulting Map.

Map.groupBy() calls callbackFn for each element in the items iterable and uses the returned values as keys in the resulting Map. The resulting Map has entries for each unique key returned by callbackFn, and each entry value is an array containing all the elements from the original items iterable that had the same key.

A Practical Example

  • Let’s illustrate this with a practical example. Suppose you have an array of orders, and you want to group these orders by their status. Here’s how you can do it with Map.groupBy():
const orders = [
  { id: 1, status: "shipped", amount: 100 },
  { id: 2, status: "pending", amount: 200 },
  { id: 3, status: "shipped", amount: 150 },
  { id: 4, status: "delivered", amount: 300 },
  { id: 5, status: "pending", amount: 50 },
];

const groupedOrders = Map.groupBy(orders, ({ status }) => status);
Enter fullscreen mode Exit fullscreen mode
  • In this example, the callbackFn returns the status property of each order. The resulting groupedOrders Map will look like this:
Map(3) {
  "shipped" => [
    { id: 1, status: "shipped", amount: 100 },
    { id: 3, status: "shipped", amount: 150 }
  ],
  "pending" => [
    { id: 2, status: "pending", amount: 200 },
    { id: 5, status: "pending", amount: 50 }
  ],
  "delivered" => [
    { id: 4, status: "delivered", amount: 300 }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why Should You Use Map.groupBy()?

The benefits of using Map.groupBy() include:

  • Order Preservation: Map maintains the order of insertion, which can be important for certain applications.

  • Flexible Key Types: Unlike objects, Map keys can be any value (including objects, functions, etc.), not just strings or symbols.

  • Efficient Lookups: Map provides efficient key-value pair lookups, especially useful for large datasets.


Promise.withResolvers

Promise.withResolvers is a static method introduced in ECMAScript 2024 that simplifies creating a promise along with its associated resolve and reject functions. This is particularly useful in scenarios where you need to control the resolution or rejection of a promise from outside its initial scope.

Syntax

Here’s how you use Promise.withResolvers:

const { promise, resolve, reject } = Promise.withResolvers();
Enter fullscreen mode Exit fullscreen mode

How Does It Work?

Promise.withResolvers returns an object containing three properties:

  1. promise: The Promise object that you can await or chain .then() and .catch() methods on.

  2. resolve: The resolve function for the promise, which you can call to mark the promise as fulfilled.

  3. reject: The reject function for the promise, which you can call to mark the promise as rejected.

A Practical Example

  • Let’s see Promise.withResolvers in action with a practical example. Imagine you need to fetch some data and want to control when the promise is resolved or rejected based on certain conditions.
const { promise, resolve, reject } = Promise.withResolvers();

function fetchData(url) {
  // Simulate an async operation with setTimeout
  setTimeout(() => {
    if (url) {
      resolve({ data: "Sample Data from " + url });
    } else {
      reject(new Error("URL is required"));
    }
  }, 2000);
  return promise;
}

// Usage
fetchData("https://api.example.com/data")
  .then(response => {
    console.log("Data fetched:", response);
  })
  .catch(error => {
    console.error("Error fetching data:", error);
  });
Enter fullscreen mode Exit fullscreen mode
  • In this example, fetchData function returns the promise created by Promise.withResolvers. Inside the function, we simulate an asynchronous operation using setTimeout. Based on the provided url, we either call resolve with the fetched data or reject with an error.

Why Should You Use Promise.withResolvers?

The key advantages of Promise.withResolvers include:

  • Convenience: It consolidates the creation of a promise and its resolver functions into a single step, making your code cleaner and more concise.

  • Readability: By explicitly having resolve and reject functions available, it’s clear how and when the promise will be resolved or rejected.

  • Flexibility: It allows for more complex asynchronous workflows without having to nest or chain multiple promise constructors.

Show Us Your Love

Subscribe to my YouTube channel for in-depth coding tutorials and projects: Coding With JD

Ready for More? 🚀

  • Keep experimenting, keep learning, and never be afraid to break things (in a safe coding environment, of course! 😅).

  • Want to stay connected? Follow me on Instagram @codingwithjd for more coding tips, tricks, and even some bad programming jokes. 😉

Top comments (0)