user9256397
user9256397

Reputation:

ReactJs calculate sum of all values present in Table column

I am having a Bootstrap-table rendering values from service called in componentDidMount().

Example of my table -

  Col1      Col2 Col3
   1         2    3
   4         5    6
   7         8    9
  SumValue  15   18 //This last row holds sum of all values

How to calculate SumValue of all the values present in col1 and display in Footer.

Below is the code how i am using react-row for mapping data to rows. And value is the variable holding data of all columns present in json file returned from service, after setting it to the component's state.

    {this.state.value && this.state.value.map(function (value, ind) {
                    return <Row key={ind} item={value}></Row>
                })
            }

Initializing state

   constructor(props){
    super(props)
    {
        this.state ={
            value: [],   //Initializing an array
            SumValue: '',
            default: false,               
        }            
    }

Setting state

  fetch('https://www.serviceUrl.com')
   .then(res => res.json())
    .then(value => {
        this.setState({
            value: value.empRecords,  //Here its getting all records from json
            default: false
        });        
    })

Let me know guys if any more information is required.

Upvotes: 0

Views: 13879

Answers (2)

Nijat Aliyev
Nijat Aliyev

Reputation: 876

1) initial columnNames and array list

state = {
    callList: [],
    columnModel: [
       { columnName: "date" },
       { columnName: "totalCalls" },
       { columnName: "answeredCalls" },
       { columnName: "abandonedCalls" },
       { columnName: "abandonRate" },
       { columnName: "avgAnswerSpeed" },
    ]

};

2) Get data from api and prepare array data

try {
    const { errors, list, success } = (await apiService.getCalls(request)).data;
    if (success) {

        // first list is normal numbers count only, 
        // if you want count avg sum for some columns send second param array list and include column names
        // now i want count avg for 'abandonRate', 'avgAnswerSpeed' , others just count sum

        this.setState({ 
            callList: list,
            callListSum: this.sumCount(
                list, 
                ['abandonRate', 'avgAnswerSpeed']
            )
        })
    }
} catch (error) {
    console.log(error);
}

sumCount = (list = [], avgColumns = []) => {
    const sum = {};

    // count numbers
    list.map((item) => {
        Object.entries(item).map(([key, val]) => {
            if (typeof (val) === 'number') {
                sum[key] = sum[key] ? (sum[key] + val) : val;
            }
        })
    });
    
    // count avg
    avgColumns.map(key => {
        if (sum[key]) {
            sum[key] = sum[key] / list.length;
        }
    })
    return sum;
}


3) Render data

<table>
    <thead>
        <tr style={{ backgroundColor: "#F5F7FA" }}>
            {
                this.state.columnModel.map((item, i) =>
                  <th key={i}> {item.columnName}</th>
                )
            }
        </tr>
    </thead>
    <tbody>
        {
            this.state.callList.map(
            (info, index) => (
                <tr
                    key={index}
                >
                    {
                        this.state.columnModel.map((item, i) =>
                           (
                            <td key={i}>
                              {info[item.columnName]}
                            </td>
                           )
                        )
                    }
                </tr>
            )
        )}
        {/* Render sum area */}
        <tr 
            style={{ backgroundColor: "#F5F7FA" }}
        >
            {
                this.state.columnModel.map((item, i) =>
                    (
                        <td style={{ fontWeight: "bold" }} >
                         {this.state.callListSum[item.columnName]}
                        </td>
                    )
                )
            }
        </tr>
    </tbody>
</table>

Upvotes: 0

Miguel Calder&#243;n
Miguel Calder&#243;n

Reputation: 3091

I would get the sum using reduce:

const SumValue = this.state.value && this.state.value.reduce((a, v) => a + v, 0)

Upvotes: 1

Related Questions