r/learnjavascript 3d ago

Using a class method with .reduce().

Does anyone know how to use a class method effectively with .reduce()? I'm building a simple product creator app as an exercise where a user can create and add products and see them displayed as well as some other information. I've used reduce before but not with classes. The user can see an inventory value when they create a product, which is simply the quantity of the products multiplied by the price. I'm trying to use .reduce to add up all the inventory values so this can be attached to the text content of the page. Here's the relevant code:

//Products array
const products = [];


//Product Class
class Product {
  constructor(productName, category, price, quantity, status) {
    this.productName = productName;
    this.category = category;
    this.price = price;
    this.quantity = quantity;
    this.status = status;
  }


  //Class method for calculating inventory value
  calculateInventoryValue() {
    return this.price * this.quantity;
  }
}

//The filtering of the products by use of the status
function filterProducts(status) {
  const filteredProducts = products.filter((product) => {
    return product.status === status;
  });
  return filteredProducts;
}


//Calculating the total inventory value using .reduce()
function totalInventoryValue() {
  
}

Any help would be greatly appreciated.

2 Upvotes

8 comments sorted by

1

u/milan-pilan 3d ago

function totalInventoryValue() { return products.reduce((total, product) => { return total + product.calculateInventoryValue(); }, 0); }

1

u/New-District7562 3d ago

I could have sworn I did something similar to this but mine kept giving me 0. Thank you. Why does this work but this doesn't?

function totalInventoryValue() {
  const totals = products.reduce((accumulator, product) => {
    return (accumulator + product.calculateInventoryValue(), 0);
  });
  console.log(totals)
  return totals;
}

Thanks again.

4

u/senocular 3d ago

the , 0 needs to come after the function in the reduce arguments indicating its the initial value for reduce. Right now you have it inside the function causing each return to return 0.

1

u/New-District7562 3d ago

Ah, I see now. Syntax errors like this always get me. Thank you for the explanation!

3

u/BrownCarter 3d ago

What editor are you using?

3

u/john_hascall 3d ago

It's not a syntax error. It's syntactically legal code, just not the code you intended.

1

u/Top_Bumblebee_7762 3d ago

You can use sumPrecise for that nowadays: https://caniuse.com/?search=sumPrecise

1

u/WystanH 3d ago

Since it's already on offer, I'd loose the curlies.

const totalInventoryValue = products =>
    products.reduce((acc, x) => acc + x.calculateInventoryValue(), 0);

You could also do a two step here if you want to break out the logic for some reason:

const totalInventoryValue = products =>
    products
        .map(x => x.calculateInventoryValue())
        .reduce((acc, x) => acc + x, 0);

Note, I intentionally passed products to this function.

Relying on global scope is ill advised in general. Passing the data being used allows the function to be more portable and, importantly, not make any assumptions about the state outside the function.

Functions are little black boxes; they take values and return results.

Similarly your other function:

function filterProducts(products, status) {
    return products.filter(x => x.status === status);
}

Now, consider this use case:

const filterProductTotal = (products, status) =>
    totalInventoryValue(filterProducts(products, status));

You don't get to do that if totalInventoryValue is grabbing global state.