Search code examples
reactjslodashweb3js

_.each loop render tablerows with button. OnClick function affecting all rows?


I'm trying to render a table which will display a products details and have a buy button as the final column of each row. The problem is currently when I click the buy button every product in the table is bought. Any ideas?

var TableRows = []

_.each(this.state.productids, (value, index) => {
  TableRows.push(
    <TableRow>
      <TableRowColumn>{this.web3.toDecimal(this.state.productids[index])}</TableRowColumn>
      <TableRowColumn>{this.web3.toUtf8(this.state.names[index])}</TableRowColumn>
      <TableRowColumn>{this.web3.toUtf8(this.state.descriptions[index])}</TableRowColumn>
      <TableRowColumn>{(this.web3.toDecimal(this.state.prices[index])) }</TableRowColumn>
      <TableRowColumn>{this.state.owners[index]}</TableRowColumn>
      <RaisedButton label='Buy' onClick={this.state.productContract.buyProduct.sendTransaction(this.state.productids[index], { from: this.web3.eth.accounts[1], value:this.state.prices[index], gas:2000000 })} primary />
    </TableRow>
  )

Solution

  • Two things that I did:

    1. I used the _.map() function instead of the _.each() function because it is faster and follows the React pattern of immutability.
    2. You were missing a <TableRowColumn> element wrapping around your <RaisedButton> element, which is why the button was applying the (click) to the entire row instead of just the <RaisedButton> element.

    // Your code:
    /* var TableRows = []
    
    _.each(this.state.productids, (value, index) => {
      TableRows.push(
        <TableRow>
          <TableRowColumn>{this.web3.toDecimal(this.state.productids[index])}</TableRowColumn>
          <TableRowColumn>{this.web3.toUtf8(this.state.names[index])}</TableRowColumn>
          <TableRowColumn>{this.web3.toUtf8(this.state.descriptions[index])}</TableRowColumn>
          <TableRowColumn>{(this.web3.toDecimal(this.state.prices[index])) }</TableRowColumn>
          <TableRowColumn>{this.state.owners[index]}</TableRowColumn>
          <RaisedButton label='Buy' onClick={this.state.productContract.buyProduct.sendTransaction(this.state.productids[index], { from: this.web3.eth.accounts[1], value:this.state.prices[index], gas:2000000 })} primary />
        </TableRow>
      )*/
      
    const TableRows = _.map(this.state.productids, (value, index) => {
      return <TableRow>
        <TableRowColumn>{this.web3.toDecimal(this.state.productids[index])}</TableRowColumn>
          <TableRowColumn>{this.web3.toUtf8(this.state.names[index])}</TableRowColumn>
          <TableRowColumn>{this.web3.toUtf8(this.state.descriptions[index])}</TableRowColumn>
          <TableRowColumn>{(this.web3.toDecimal(this.state.prices[index])) }</TableRowColumn>
          <TableRowColumn>{this.state.owners[index]}</TableRowColumn>
          <TableRowColumn>
            <RaisedButton label='Buy' onClick={() => this.state.productContract.buyProduct.sendTransaction(this.state.productids[index], { from: this.web3.eth.accounts[1], value:this.state.prices[index], gas:2000000 })} primary />
          </TableRowColumn>
        </TableRow>
    });