ubaid
ubaid

Reputation: 15

Can't calculate total in React component

I am a total newbie in React and my problem is this: I have a component called 'IncExpSummary' which shows to total amount of income and expenses. It receives data of income and expenses from redux store by using 'mapStateToProps'. I also have a selector function called 'total' which map over the array of object and return total(this function is working fine). The problem is every time I add new income or expense the total is not calculated but the amount of new item is add at the end of previous number.

The IncExpSummary looks like this:

import React from 'react';
import { connect } from 'react-redux';
import total from '../selectors/total.js';

class IncExpSummary extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <div className="income-summary">
          <p className="income-summary-text">Income: {this.props.totalIncome}</p>

        </div>
        <div className="expense-summary">
          <p className="expense-summary-text">Expense: {this.props.totalExpense}</p>

        </div>
      </div>
    )
  }
}

function mapStateToProp(state) {
  return {
    totalIncome: total(state.income),
    totalExpense: total(state.expenses)
  }
}

export default connect(mapStateToProp)(IncExpSummary);

The 'total' function looks like this:

export default (data) => {
  if (data.length > 0) {
    return data.map((item) => {
      return item.amount;
    }).reduce((total, amount) => {
      return total + amount;
    });
  } else {
    return 0;
  }
}

After adding two income with amount 30 and 20 each I expected the output to be 50, but the actual output is 3020.

Complete project is available here: https://codesandbox.io/s/l4k6q6ok5q

Upvotes: 0

Views: 309

Answers (3)

Murtaza Hussain
Murtaza Hussain

Reputation: 4285

just change the line in the 'total' function from returning the string amount:

return item.amount;

to below for return integer amount:

return +item.amount;

Upvotes: 0

Jack Bashford
Jack Bashford

Reputation: 44107

You need to parse to a number:

export default (data) => {
  if (data.length > 0) {
    return data.map(({ amount }) => parseFloat(amount)).reduce((total, amount) => total + amount);
  } else {
    return 0;
  }
}

Upvotes: 0

leroydev
leroydev

Reputation: 2945

That's because the item.amount values are strings. This results in the strings getting concatenated.

Change it to the following so the strings will be parsed as floats and it will work properly:

export default (data) => {
  if (data.length > 0) {
    return data.map((item) => {
      return parseFloat(item.amount);
    }).reduce((total, amount) => {
      return total + amount;
    });
  } else {
    return 0;
  }
}

Upvotes: 3

Related Questions