0

I am currently making a Recipe app and I am pulling data from this API called edamame. I imported cards from Material UI and imported it into my .js file that calls the API for the data. I stored the data in a const called recipes but I am struggling to get the data to appear in my imported cards. I can create cards locally without importing from Material UI and make the API data show just fine. But once Material UI shows up, I start having problems. How should I approach this?

MealPlan.Js (calls the API and stores data)

import React, { useState, useEffect } from "react";
import style from "./recipe.module.css";
import "./App.css";
import NavigationBar from "./NavigationBar";
import Card from "./card";
import { Grid } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles({
    gridContainer: {
        paddingLeft: "20px",
        paddingRight: "20px",
    },
});

export default function MealPlan() {
    //  below we define the useStates

    const [recipes, setRecipes] = useState([]); //Recipes pulled from the api through the search function are stored in this const
    const [search, setSearch] = useState("");
    const [query, setQuery] = useState("chicken");
    const APP_ID = "removed";
    const APP_KEY = "removed";

    useEffect(() => {
        //dispatch call to fetch items // get recipes runs the function when useEffect is active
        getRecipes(); // eslint-disable-next-line
    }, [query]); //only refreshes when query is called

    const getRecipes = async () => {
        const response = await fetch(
            `https://api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}`
        ); 
        
        const data = await response.json();  
        setRecipes(data.hits);
        console.log(data.hits);
    };


//my personal card
    const MealPlanCard = ({ title, calories, image, ingredients }) => {
        const round = Math.round(calories);

        return (
            <div className={style.recipe}>
                <h1>{title}</h1>
                <img className={style.image} src={image} alt="" />
            </div>
        );
    };

    return (

                {recipes.slice(0, 1).map((recipe) => (
                    <MealPlanCard
                        key={recipe.recipe.label}
                        title={recipe.recipe.label}
                        calories={recipe.recipe.calories}
                        image={recipe.recipe.image}
                        ingredients={recipe.recipe.ingredients}
                    />
                ))}
            </div>

<Grid container spacing={4} className={classes.gridContainer}>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
                <Grid item xs={12} sm={6} md={4}>
                    <Card />
                </Grid>
            </Grid>
        </div>
    );
}

Here is the jsx for the imported cards from Material UI

import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles({
    root: {
        minWidth: 200,
    },
    bullet: {
        display: "inline-block",
        margin: "0 2px",
        transform: "scale(0.8)",
    },
    title: {
        fontSize: 14,
    },
    pos: {
        marginBottom: 12,
    },
});

export default function SimpleCard() {
    const classes = useStyles();
    const bull = <span className={classes.bullet}>•</span>;

    return (
        <Card className={classes.root}>
            <CardContent></CardContent>
            <CardActions>
                <Button size="small">Button</Button>
            </CardActions>
        </Card>
    );
}

Here is how my page currently looks https://i.stack.imgur.com/plUIa.jpg

My Goal is to populate the imported cards on the bottom, with the contents of my personal card on the top. How can I do that?

Aroxis
  • 67
  • 5

1 Answers1

0

If I understood you correctly, you want your functional component SimpleCard to receive data from MealPlan...

If that is the case, consider the following:

SimpleCard.js

export default function SimpleCard(props) {
    const classes = useStyles();
    const bull = <span className={classes.bullet}>•</span>;

    return (
        <Card className={classes.root}>
            <CardContent>{props.ingredient}</CardContent>
            <CardActions>
                <Button size="small">{props.calories}</Button>
            </CardActions>
        </Card>
    );
}

And on your MealPlan.js you import this file

import SimpleCard from 'pathTo/SimpleCard'

and instead of rendeind Card you should render SimpleCard - that you have imported and pass down your variables as props (nutrition, calories...)

<Grid item xs={12} sm={6} md={4}>
      <SimpleCard 
           ingrediend={"banana"}
           calories={40}
      />
</Grid>

Basically the concept here is to create components such as the one you created - SimpleCard and populate it the data that you pass over it, called props, like ingredient and calories.

Therefore you have multiple instances of SimpleCard with diferent data on them.

<Grid item xs={12} sm={6} md={4}>
      <SimpleCard 
           ingrediend={"chocolate"}
           calories={100}
      />
</Grid>
<Grid item xs={12} sm={6} md={4}>
      <SimpleCard 
           ingrediend={"banana"}
           calories={40}
      />
</Grid>

and so on!

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Hi Felipe. Thanks for the tips, I gave me a general direction but my goal is to not manually populate the "Ingredient" and "Calories". My Goal is to take that data from the API and display it on my card. For example, please look at the "Const MealPlanCard". You can see that it is taking the Values "{ title, calories, image, ingredients }" which are from the API itself. I mapped each of those values to the to the name on the APIs side. For example "title={recipe.recipe.label}". So my goal is to get the contents of {recipe.recipe.label} onto my new card. – Aroxis Apr 17 '21 at 22:42