Home > database >  getting NaN when adding elements in an array
getting NaN when adding elements in an array

Time:11-18

ive tried modifying it in a thousand different ways and im still not sure what the issue is. some help would be greatly appreciated. the objective would be to add as if it were a total in a shopping cart. as new products and prices get added - the total price would update.

i added the html so you can see the NaN being displayed. im relying on VALORtotal and reduce here.

let array = [0];


function adddata() {
  let cproducto = document.getElementById("producto");
  let cprecio = document.getElementById("precio");

  let VALUEcprecio = cprecio.value
  //table============
  let table = document.getElementById("dymanictable");

  let rowCount = table.rows.length;
  let row = table.insertRow(rowCount);

  //insetar
  row.insertCell(0).innerHTML = cproducto.value;
  row.insertCell(1).innerHTML = cprecio.value;

  //sumar
  let VALORtotal = 0
  //armo formula de suma
  const suma = array.reduce((a, b) => {
    return a.VALUEcprecio   b.VALUEcprecio
  });
  //le agrego al 0 su valor nuevo
  VALORtotal = VALORtotal   suma
  console.log(VALORtotal)

  // add todos los precios y display 
  row.insertCell(2).innerHTML = VALORtotal;

  //mostrar objeto que se va a agregar
  let objeto = new PRODUCTO(cproducto.value, VALUEcprecio)
  console.log(objeto)

  //mostrar array completo
  array.push(objeto);
  console.log(array);
}

class PRODUCTO {
  constructor(producto, precio) {
    this.producto = producto,
      this.precio = precio;
  }
}
<table>
  <!--INPUT-->
  <tr>
    <td>Producto:</td>
    <td><input type="text" id="producto"></td>
  </tr>
  <tr>
    <td>Precio:</td>
    <td><input type="text" id="precio"></td>
  </tr>
  <tr>
    <td>
      <!--BOTTON ADD-->
      <input type="button" id="add" value="Add" onclick="adddata()">
    </td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>

<table id="dymanictable" cellpadding="2">
  <tr>
    <td><b>producto</b></td>
    <td><b>precio</b></td>
    <td><b>total</b></td>

  </tr>
</table>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I believe you have a type problem here.

First of all you push objects to an array you initiated with a number (here array=[0])

Then, the return type of your input elements is a string. That's fine for the product name, but for the price you will want to do some conversion here!

You are getting NaN because you are adding apples and bananas.

Try this code here.

  1. we parse the price to a float
  2. We keep your array of products, but by using map, we extract the price of the product.
  3. We then apply reduce on the array of prices returned by map

Note:

I've changed the behaviour of the app so that the total on one row includes the value of the product shown on that row. It seemed to me that this behaviour made more sense. Feel free to change it back to your preferred way obviously

class PRODUCTO {
  constructor(producto, precio) {
    (this.producto = producto), (this.precio = precio);
  }
}
let productArray = [];

function addData() {
  let cproducto = document.getElementById("producto");
  let cprecio = document.getElementById("precio");

  let VALUEcprecio = parseFloat(cprecio.value);
  //table============
  let table = document.getElementById("dymanictable");

  let rowCount = table.rows.length;
  let row = table.insertRow(rowCount);

  //insetar
  row.insertCell(0).innerHTML = cproducto.value;
  row.insertCell(1).innerHTML = cprecio.value;

  //sumar
  let VALORtotal = 0;

  //mostrar objeto que se va a agregar
  let objeto = new PRODUCTO(cproducto.value, VALUEcprecio);
  console.log(objeto);

  //mostrar array completo
  productArray.push(objeto);

  console.log(productArray);
  const suma = productArray
    .map((obj) => obj.precio)
    .reduce((acc, next) => acc   next);
  //le agrego al 0 su valor nuevo
  VALORtotal = VALORtotal   suma;
  console.log(VALORtotal);

  // add todos los precios y display
  row.insertCell(2).innerHTML = `${VALORtotal}`;
}
<table>
  <!--INPUT-->
  <tr>
    <td>Producto:</td>
    <td><input type="text" id="producto" /></td>
  </tr>
  <tr>
    <td>Precio:</td>
    <td><input type="text" id="precio" /></td>
  </tr>
  <tr>
    <td>
      <!--BOTTON ADD-->
      <input type="button" id="add" value="Add" onclick="addData()" />
    </td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>

<table id="dymanictable" cellpadding="2">
  <tr>
    <td><b>producto</b></td>
    <td><b>precio</b></td>
    <td><b>total</b></td>
  </tr>
</table>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You are not using reduce function correctly. It needs an initial value to start and then give current value and current loop value to perform operations.

You need to use your reduce function like an example given -

 const array = [
    {
        VALUEcprecio: '10.15',
    },
    {
        VALUEcprecio: '15',
    },
    {
        VALUEcprecio: 20,
    }
 ]
 const suma = array.reduce((acc, val) => {
    // Added parseFloat to handle any time of value for addition
    return acc   parseFloat(val.VALUEcprecio)
 }, 0);
 console.log(suma) // this will give correct output.
  • Related