Understanding JavaScript Approaches: Using Filter and Map Over ForEach with Nullish Coalescing

04th September 2024
understanding-nullish-operator-and-filter-map

Introduction

In this blog am going to show how you can leverage filter and map along with Nullish Coalescing to write advanced clean and efficient code. I share two approaches with you one with forEach and another with filter and map

Use Case

Say you want to create a "result" object. Say this "result" object is to be consumed by a third party app. This Third party app requires "inStock","outofStock" and "newStock" and also requires a custom property attached with each object

Initial data and brief explanation

Imagine you get 2 sets of data from say 2 different API's or something..One "fruitsInStore" and other "newStock".

const fruitsInStore = [
              {
                id: 1,
                name: "Apple",
                inStock: true,
              },
              {
                id: 2,
                name: "Banana",
                inStock: true,
              },
              {
                id: 3,
                name: "Strawberry",
                inStock: false,
              },
              {
                id: 4,
                name: "Mango",
                inStock: false,
              },
            ];
            
            const newStock = [
              { id: 101, name: "Cherry", inStock: true },
              { id: 102, name: "Blueberry", inStock: true },
            ];
          

Lets see 2 approaches

Approach 1


              const inStock = fruitsInStore.filter((x) => x.inStock);
              const outStock = fruitsInStore.filter((x) => !x.inStock);
              const allFruits = () => {
              let x = [];
              if (inStock)
                inStock.forEach((y) => {
                  x.push({ ...y, orderAgain: "no" });
                });
              if (outStock)
                outStock.forEach((y) => {
                  x.push({ ...y, orderAgain: "yes" });
                });
              if (newStock)
                newStock.forEach((y) => {
                  x.push({ ...y, orderAgain: "maybe" });
                });
              return x;
            };

Pros -Clear logic flow; easy to understand for beginner
Cons -More verbose; requires multiple iterations over the data.

Approach 2

const allFruits1 = () => [
              ...fruitsInStore
                .filter((x) => x.inStock)
                .map((z) => ({ ...z, orderAgain: "no" })),
              ...fruitsInStore
                .filter((x) => !x.inStock)
                .map((z) => ({ ...z, orderAgain: "yes" })),
              ...newStock,
            ];

Pros -Concise,Readible,Maintainable
Cons -May be less intuitive for new programmers or those not familiar with functional programming concepts.

Lets dwelve a bit further and breakdown the code.

Filtering - We filter fruitsInStore object based on stock flag. Basically we created 2 arrays.
Mapping - Transforms each filtered array into an object and you can add property if you wish.For eg I add a property "orderAgain"
Spread OperatorThe spread operator (...) concatenates the results of the two mapped arrays and the newStock array into a single array.This leads to a flat array containing all fruits, each with the appropriate orderAgain status
Nullish Coalescing Operator (??)ensures that if the result of the map is null or undefined (which shouldn't happen in this case, but it's a good safeguard), an empty array is used instead. This allows us to spread the result into the final array.By using this we are ensured our code is more resilient and error-proof to unexpected values

Conclusion

We saw two approaches above. The Approach 2 is generally preferred for its conciseness and readability, making it easier to maintain and understand. It leverages JavaScript's functional programming capabilities, which can lead to cleaner and more efficient code.We also learnt the benefit of Null Coalescing operator.

Email me at "techspacedeck@gmail.com" incase you have queries. Alternatively, you can fill the "CONTACT" form or drop a comment below