skip to Main Content

Im trying to make a recipe website in react you have the code below i solved one error by adding the ? where the mapping is but nothing shows on the browser and if i remove the ? i get this error:
Cannot read properties of undefined (reading ‘map’)
TypeError: Cannot read properties of undefined (reading ‘map’)
Any help on how to make it work?
Also if i have the ? or the cuisine && i get error 401 from spoonacular and idk why, some guy on youtube did kinda the same and didnt have any problems

import React, {useEffect, useState} from 'react';
import styled from 'styled-components';
import {motion} from 'framer-motion';
import {Link, useParams} from 'react-router-dom';


function Cuisine() {
    const[cuisine, setCuisine] = useState([]);
    let params = useParams();

    const getCuisine = async (name) => {
        const data = await fetch(
            'https://api.spoonacular.com/recipes/complexSearch?apiKey=${process.env.REACT_APP_API_KEY}&cuisine=${name}'
        );
        const recipes = await data.json();
        setCuisine(recipes.results);
    };
    useEffect(() => {
        getCuisine(params.type);
       //console.log(params.type);
    }, [params.type]);

  return (
    <Grid>
        {cuisine?.map((item) => {
            return(
                <Card key={item.id}>
                    <img src={item.image} alt=""/>
                    <h4>{item.title}</h4>
                </Card>
            );
        })}
    </Grid>
  )
}

const Grid = styled.div`
    display:grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    grid-gap: 3rem;
`;

const Card = styled.div`
    img{
        width: 100%;
        border-radius: 2rem;
    }
    a{
        text-decoration: none;
    }
    h4{
        text-align: center;
        padding: 1rem;
    }
`;
export default Cuisine;

`

I added the ? and also the cuisine && cuisine thing but still map rendering

type here

3

Answers


  1. Chosen as BEST ANSWER

    I managed to fix it it seems the name variable from this line: https://api.spoonacular.com/recipes/complexSearch?apiKey=${process.env.REACT_APP_API_KEY}&cuisine=${name} wasnt written properly or idk i just deleted and rewrote name and it worked


  2. error: Cannot read properties of undefined (reading ‘map’) TypeError: Cannot read properties of undefined (reading ‘map’)

    This is because the (usually) .map() method is called before the data from the API request is ready. Therefore, adding ?.map() AKA optional chaining fixes this problem. In layman’s terms, I am waiting for the data to be ready before rendering the component.

    Any help on how to make it work?

    Try this:

    import React, {useEffect, useState} from 'react';
    import styled from 'styled-components';
    import {motion} from 'framer-motion';
    import {Link, useParams} from 'react-router-dom';
    
    
    function Cuisine() {
        const[cuisine, setCuisine] = useState([]);
        let params = useParams();
    
        const getCuisine = async (name) => {
            const data = await fetch(
                `https://api.spoonacular.com/recipes/complexSearch?apiKey=${process.env.REACT_APP_API_KEY}&cuisine=${name}`
            );
            const recipes = await data.json();
            setCuisine(recipes.results);
        };
        useEffect(() => {
            getCuisine(params.type);
           //console.log(params.type);
        }, [params.type]);
    
      return (
        <Grid>
    
            {cuisine?.length > 0 && cuisine?.map((item) => {
                return(
                    <Card key={item.id}>
                        <img src={item.image} alt=""/>
                        <h4>{item.title}</h4>
                    </Card>
                );
            })}
        </Grid>
      )
    }
    
    const Grid = styled.div`
        display:grid;
        grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
        grid-gap: 3rem;
    `;
    
    const Card = styled.div`
        img{
            width: 100%;
            border-radius: 2rem;
        }
        a{
            text-decoration: none;
        }
        h4{
            text-align: center;
            padding: 1rem;
        }
    `;
    export default Cuisine;
    

    Check if the length of the cuisine (when the data is ready) > 0, if so, render the component, else don’t render the component.

    Login or Signup to reply.
  3. For debugging things like this, I find it helpful to first slice down your problem. In your case, you struggle to display the data, because you haven’t solved the previous problem of getting the data.

    My guess is your display logic works fine, the problem is the API call you are doing doesn’t return any data, so there is nothing to map over and to display.

    You mention you get a 401 Unauthorized, in that case, the API won’t return any data. So you need to figure that out first.

    One immediate problem with your API call I see is your string is wrong, you are trying to use Template Literals/Template String, but you are using normal quotes. Which will not replace ${process.env.REACT_APP_API_KEY} but just print it as it is. Try this instead:

    `https://api.spoonacular.com/recipes/complexSearch?apiKey=${process.env.REACT_APP_API_KEY}&cuisine=${name}`
    

    If it still doesn’t work, then I would console.log() your data, process.env.REACT_APP_API_KEY, and name to be sure everything works there.

    I added the ? and also the cuisine && cuisine thing but still map rendering

    Regarding this, that’s definitely correct and you should keep it. Since you are getting the data asynchronously. You will need to handle the case where the data is not available yet.

    I hope that helps

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search