0

I want to build menu for my website with food cards. I fetch data(name of food, recipe, price) from my rest api and then i show this data on my react app. In this food card I have three radio buttons for mini, middle and maxi prices. When I change button on one card it changes on all cards. First image, when price 35 and

Second image, when I change price on first card, but it changes on all cards

this is my code:

constructor(props){
    super(props);
    this.state = {
        shavermas : [],
        price : ''
    };
}

componentDidMount(){
    this.findAllPosts();
}

findAllPosts(){
    axios.get("http://localhost:8080/api/shaverma/all")
        .then(response => response.data)
        .then((data) => {
            this.setState({shavermas: data})
        });
}

onChange = e =>{
    this.setState({price : e.target.value})
}

 render(){
let {price} = this.state;
const {shavermas} = this.state;
return(
  <>
      {shavermas.map((shaverma, index) => (
    <div className="food-cart">
        <div className="product-img-div">
        <img
            src={shavermaPhoto}
            className="d-inline-block product-img"
            alt="shaverma"
          /> 
        </div>
        <div className="food-cart-body">
            <div>
            <h3>Шаверма <span>{shaverma.foodName}</span></h3>
            <p>{shaverma.recipe}</p>
                <form className="radio-buttons">
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMini} onChange={this.onChange} checked={price.charAt(0) == '' ? shaverma.priceMini : price == shaverma.priceMini}/>
                            <span>Mini</span>
                        </label>
                    </div>
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMiddle} onChange={this.onChange} checked={price == shaverma.priceMiddle}/>
                            <span>Middle</span>
                        </label>
                    </div>
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMaxi} onChange={this.onChange} checked={price == shaverma.priceMaxi} />
                            <span>Maxi</span>
                        </label>
                    </div>
                </form>
                <div className="food-cart-footer">
                    <strong>{price.charAt(0) === '' ? shaverma.priceMini : price}₴</strong>
                    <p>Хочу!</p>
                </div>
            </div>
        </div>
    </div>
      ))}
    </>
)

}

1
  • Could you supply a working example in sites like Code Sandbox? Commented Sep 2, 2020 at 12:23

2 Answers 2

1
You are using common Price state for all cards, you have to use price property for individual card,
Use it like this : 

    onChange = (e,index) =>{
    let newShavermas = this.state.shavermas ;
    newShavermas[index].price=e.target.value;
    this.setState({price : e.target.value})
}
and while fetching the result include price property in each record
    findAllPosts(){
    axios.get("http://localhost:8080/api/shaverma/all")
        .then(response => response.data)
        .then((data) => {
            let dataVal = data.map(ele=>ele.Price='');
            this.setState({shavermas: dataVal })
        });
}


and in return call onChange like this :

    return(
  <>
      {shavermas.map((shaverma, index) => (
    <div className="food-cart">
        <div className="product-img-div">
        <img
            src={shavermaPhoto}
            className="d-inline-block product-img"
            alt="shaverma"
          /> 
        </div>
        <div className="food-cart-body">
            <div>
            <h3>Шаверма <span>{shaverma.foodName}</span></h3>
            <p>{shaverma.recipe}</p>
                <form className="radio-buttons">
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMini} onChange={(e)=>this.onChange(e,index)}  checked={shaverma.price.charAt(0) == '' ? shaverma.priceMini : price == shaverma.priceMini}/>
                            <span>Mini</span>
                        </label>
                    </div>
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMiddle} onChange={(e)=>this.onChange(e,index)}  checked={shaverma.price == shaverma.priceMiddle}/>
                            <span>Middle</span>
                        </label>
                    </div>
                    <div className="radio">
                        <label className="btn-radio">
                            <input type="radio" value={shaverma.priceMaxi} onChange={(e)=>this.onChange(e,index)}  checked={shaverma.price == shaverma.priceMaxi} />
                            <span>Maxi</span>
                        </label>
                    </div>
                </form>
                <div className="food-cart-footer">
                    <strong>{shaverma.price.charAt(0) === '' ? shaverma.priceMini : shaverma.price}₴</strong>
                    <p>Хочу!</p>
                </div>
            </div>
        </div>
    </div>
      ))}
    </>
)

   
Sign up to request clarification or add additional context in comments.

1 Comment

Tried to fix the tab error to move the text out of the code block, seems to be reverted
0

This is because all of you cart items are looking at the same state value!

onChange = e =>{
   this.setState({price : e.target.value}) < --- changes price to all cards
}

To solve this, you will need to have a price inside each shaverma then change it alone.

I would suggest starting by creating a FootCart component with its own state.

Something along the line of:

class FootCart implements React.Component {
   ...
   render() {
     return (
      <div className="food-cart">
      ...
      </div>
  }
}

class Cards implements React.Component {
   ...

   render(){
     return (
       <>
        {shavermas.map((shaverma, index) => (<FootCart props/>)}
       </>
     }
}

Good Luck!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.