How to Import API data into a Material UI Card

679 Views Asked by At

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?

1

There are 1 best solutions below

1
On

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!