I am trying to make a table that implements total price but it equals Nan
how the total is calculated:
import React from 'react';
const Total = (props) => {
const {items} = props;
let total = 0
for (let i = 0; i < items.length; i++) {
total += parseFloat(items[i].price)
}
return (
<div>
<p className="text">Total Price: {total}</p>
</div>
)
}
export default Total;
we add items by two buttons, the add button and the + button:
the console shows no errors
here is the app.js:
import './App.css';
import React, {Component} from 'react';
import Items from './components/item/items'
import AddItem from './components/addItem/addItem'
import Total from './components/total/total'
class App extends Component {
state = {
items: [
{id:1, product:'Pen', price:2},
{id:2, product:'Book', price:10}
]
}
deleteItem = (id) => {
let items = this.state.items
let i = items.findIndex(item => item.id === id)
items.splice(i, 1)
this.setState({items: items})
}
addItem = (item) => {
this.setState({items: [...this.state.items, {id: this.state.items.length > 0 ? (this.state.items[this.state.items.length - 1].id + 1): 1}]
})}
addItem2 = (item) => {
this.state.items.length > 0 ? (
item.id = this.state.items[this.state.items.length - 1].id + 1
) : item.id = 1
console.log(item.id)
let items = this.state.items
items.push(item)
this.setState({items: items})
}
render() {
return (
<div className="container">
<h1>Product List React App</h1>
<div className="table">
<Items items={this.state.items} del={this.deleteItem} add={this.addItem}/>
<AddItem add={this.addItem2}/>
<Total items={this.state.items}/>
</div>
</div>
)
}
}
export default App;
here is the items.js:
import React from 'react';
const Items = (props) => {
const {items, del,add} = props;
let length = items.length
const ListItem = length ? (
items.map(item => {
return(
<div key={item.id} className="item">
<p onClick={()=>add(item.id)}>+</p>
<p>{item.product}</p>
<p>{item.price}</p>
<p className="delete" onClick={() => del(item.id)}>×</p>
</div>
)
})
) : (
<div className="text">There are no items, Try to add some.</div>
)
return (
<div>
<div className="header item">
<p>quantity</p>
<p>Product</p>
<p>Price</p>
<p>Edit</p>
</div>
{ListItem}
</div>
)
}
export default Items
the console shows the product and the price and it shows no errors until now
2
Answers
TL,DR: One of the items is either a string, undefined or anything that cannot be converted into a number.
Source: developer.mozilla.org – NaN – Description
Long Story Short:
If you’re getting a NaN (Not a Number) result, it indicates that at least one of the values in the items array’s price property cannot be successfully converted to a number using parseFloat. To prevent this issue, you should ensure that each price value is a valid number before attempting to add it to the total.
Here’s an updated version of your code that includes a check to handle potential non-numeric values:
By using parseFloat and checking if the result is a valid number using isNaN, you can prevent NaN values from being added to the total. This should help resolve the issue you’re encountering.
Another possible case scenario:
In Your Specific Case:
The issue causing NaN in the total price is in the addItem method where you’re trying to calculate the next id. Let’s fix that part:
Explanation:
This modification should prevent NaN from appearing in the total price.
Reason: your items list has an empty price. it will be either an empty string or undefined.
Solution:
correct the code as below:
So, in case the price of an item is a falsy value, it will fall back to zero and avoid the NaN.
Changed line:
parseFloat(items[i].price || 0)