Nistor Sergiu Cosmin
Nistor Sergiu Cosmin

Reputation: 15

React can't read property value

I get this error:

TypeError: Cannot read property 'value' of undefined 

when i press the Enter button in my app. I know that the problem is in my buy function because i only select the first character with product[0] but i don't know how to make it differently.

I don't know how to set up my code so that my code doesn't crash

const prices = [
  {id: "1", value: 2},
  {id: "2", value: 3},
  {id: "3", value: 2.5},
  {id: "4", value: 5.5},
  {id: "5", value: 2.75},
  {id: "6", value: 1.25},
  {id: "7", value: 7.5},
  {id: "8", value: 2},
  {id: "9", value: 4.25}
]

class FrontPanel extends Component {
  constructor(){
    super()
    this.clearMessage = this.clearMessage.bind(this);

    this.state = {
        credit: 0,
        query: "",
        message: "Please select a product!"
      }
  }

calculateRest = (money, cost) => {
  let newCredit = money - cost;
  this.setState({ credit: newCredit})
}

addToQuery = (id) => {
       this.setState(prevState => ({
          query: prevState.query + id
       }), () => {

       this.onChangeQuery()
    })
  }

clearQuery = () => {
    this.setState({
      query: ""
    })
  }

    buyMessage = () => {
  this.setState({ message: "Thank you for your purchase!"})
  setTimeout( () => {this.clearMessage()},2000)
  }


buy = () => {
  var currentQuery = this.state.query
  var product = prices.filter(number => number.id === currentQuery);
  var money = this.state.credit;
  if (money >= product[0].value) {
    this.calculateRest(money, product[0].value);
    this.clearQuery();
    this.buyMessage();
  }
  else {
    this.setState({ message: "Please add more credit!"})
  }
}
  render() {

    return (
      <div>

          <Screen
            credit={this.state.credit}
            query={this.state.query}
            message={this.state.message}/>
          <div className='buttons'>
            <button className="button" onClick={this.addCredit}>Add Credit</button>
            <button className="button" onClick={this.clearScreen}>Clear</button>
            <button className="button" onClick={this.buy}>Enter</button>
            </div>

          <div className="keybord-layout">
          <div className="keybord">
          <button onClick={e => this.addToQuery(e.target.id)} id="1">1</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="2">2</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="3">3</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="4">4</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="5">5</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="6">6</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="7">7</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="8">8</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="9">9</button>
          <button onClick={e => this.addToQuery(e.target.id)} id="0">0</button>
          </div>
          </div>
      </div>
    )
  }
}

I just want when i press enter with 2 or more values to set a message and not crash my app.

Upvotes: 0

Views: 50

Answers (2)

Tom O.
Tom O.

Reputation: 5941

Just add a length check on your array before you try to access the elements inside:

buy = () => {
  var currentQuery = this.state.query
  var product = prices.filter(number => number.id === currentQuery);
  if(product.length) { //Check the length of the array here!
      var money = this.state.credit;
      if (money >= product[0].value) {
        this.calculateRest(money, product[0].value);
        this.clearQuery();
        this.buyMessage();
     }
     else {
       this.setState({ message: "Please add more credit!"})
     }
  }
}

Upvotes: 0

Prince Hernandez
Prince Hernandez

Reputation: 3721

add a validation before doing the comparison, switch:

if (money >= product[0].value)

to:

if (product && product[0] && money >= product[0].value)

that will help you to avoid those undefined issues. maybe the currentQuery that you are using to filter your prices is not in the array, thus you get an empty array, then you will get product = [] and therefore result[0] === undefined

Upvotes: 1

Related Questions