Search code examples
javascriptreactjs

For-loop in React using cards


I'm working on recipe project. I have fetched the all data from an API like image, video, and ingredients, into the React cards.

Now I want to the ingredients for each card as per need. For example card 1 has need 5 ingredients, and card 2 has need 10 ingredients. So how can I add a for-loop for ingredients for each card?

function LiveData() {
  const [mydata, setData] = useState([]);

  const api = () => {
    fetch(
      "https://www.themealdb.com/api/json/v1/1/search.php?s=" ,
      mydata.strMeal
    )
      .then((response) => response.json())
      .then((json) => {
        setData(json.meals)
      });
  };

  useEffect(() => {
    api();
    const interval = setInterval(() => {
      api();
    }, 20000)
    return () => clearInterval(interval);
  },[]);

  return (
    <>
      <Container fluid>
        <Row xs={1} md={3} className="g-4">
          {mydata.map((res) => {
            return (
              <>
                <Col className="container-fluid mt-4">
                  <Card>
                    <Card.Img variant="top" src={res.strMealThumb} height="340px" width="500px" />
                    <Card.Body>
                      <Card.Title>{res.strMeal}</Card.Title>
                      <Card.Text>{res.strArea}</Card.Text>
                      <b>Ingredients: </b>
                      <div id='ing'>                             
                      <Card.Text>{res.strIngredient1}-{res.strMeasure1}</Card.Text>
                      <Card.Text>{res.strIngredient2}-{res.strMeasure2}</Card.Text>
                      <Card.Text>{res.strIngredient3}-{res.strMeasure3}</Card.Text>
                      <Card.Text>{res.strIngredient4}-{res.strMeasure4}</Card.Text>
                      <Card.Text>{res.strIngredient5}-{res.strMeasure5}</Card.Text>
                      <Card.Text>{res.strIngredient6}-{res.strMeasure6}</Card.Text>
                      <Card.Text>{res.strIngredient7}-{res.strMeasure7}</Card.Text>
                      <Card.Text>{res.strIngredient8}-{res.strMeasure8}</Card.Text>
                      <Card.Text>{res.strIngredient9}-{res.strMeasure9}</Card.Text>
                      <Card.Text>{res.strIngredient10}-{res.strMeasure10}</Card.Text>
                      <Card.Text>{res.strIngredient11}-{res.strMeasure11}</Card.Text>
                      <Card.Text>{res.strIngredient12}-{res.strMeasure12}</Card.Text>
                      <Card.Text>{res.strIngredient13}-{res.strMeasure13}</Card.Text>
                      <Card.Text>{res.strIngredient14}-{res.strMeasure14}</Card.Text>
                    </div>
                    <Card.Link>
                      <a
                        href={res.strYoutube}
                        target="_blank"
                       >
                         YouTube Video for {res.strMeal}
                       </a>
                      </Card.Link>
                    </Card.Body>                                  
                  </Card>               
                </Col>
              </>
            )
          })}      
        </Row>
      </Container> 
    </> 
  )                       
}

How can I apply for-loop into cards.


Solution

  • Can you try this

    import React, { useEffect, useState } from 'react';
    import { Container, Row, Col, Card } from 'react-bootstrap';
    
    function LiveData() {
      const [mydata, setData] = useState([]);
    
      const api = () => {
        fetch('https://www.themealdb.com/api/json/v1/1/search.php?s=')
          .then((response) => response.json())
          .then((json) => {
            setData(json.meals);
          });
      };
    
      useEffect(() => {
        api();
        const interval = setInterval(() => {
          api();
        }, 20000);
        return () => clearInterval(interval);
      }, []);
    
      const extractIngredients = (meal) => {
        const ingredients = [];
        for (let i = 1; i <= 20; i++) {
          const ingredient = meal[`strIngredient${i}`];
          const measure = meal[`strMeasure${i}`];
          if (ingredient) {
            ingredients.push(`${ingredient} - ${measure}`);
          }
        }
        return ingredients;
      };
    
      return (
        <>
          <Container fluid>
            <Row xs={1} md={3} className="g-4">
              {mydata.map((res) => (
                <Col key={res.idMeal} className="container-fluid mt-4">
                  <Card>
                    <Card.Img variant="top" src={res.strMealThumb} height="340px" width="500px" />
                    <Card.Body>
                      <Card.Title>{res.strMeal}</Card.Title>
                      <Card.Text>{res.strArea}</Card.Text>
                      <b>Ingredients: </b>
                      <div id="ing">
                        {extractIngredients(res).map((ingredient, index) => (
                          <Card.Text key={index}>{ingredient}</Card.Text>
                        ))}
                      </div>
                      <Card.Link href={res.strYoutube} target="_blank">
                        YouTube Video for {res.strMeal}
                      </Card.Link>
                    </Card.Body>
                  </Card>
                </Col>
              ))}
            </Row>
          </Container>
        </>
      );
    }
    
    export default LiveData;