sei-ec-remote / project-4-issues

Open an issue to receive help on project 4
0 stars 0 forks source link

trying to filter recipe by the recipeType. #138

Closed Mahider-Mengiste closed 2 years ago

Mahider-Mengiste commented 2 years ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

MERN

What's the problem you're trying to solve?

I am trying to filter a recipe in the index page by a recipe type from my recipe API

Post any code you think might be relevant (one fenced block per file)

image for the link icons

Screen Shot 2022-08-26 at 1 26 56 PM

Recipe Index - PART 1

import { 
    useState, 
    useEffect 
} from 'react'
import Card from 'react-bootstrap/Card'
import { Link } from 'react-router-dom'

import LoadingScreen from '../shared/LoadingScreen'
import { getAllRecipes } from '../../api/recipes'
import messages from '../shared/AutoDismissAlert/messages'
import ShowJumbotron from '../Jumbotron/ShowJumbotron'

const cardContainerStyle = {

    display: 'flex',
    justifyContent: 'space-around',
    flexWrap: 'wrap',
    flexDirection: 'row',
    backgroundColor: 'rgb(255, 255, 255)'
}

// RecipessIndex should make a request to the api
// To get all recipes
// Then display them when it gets them

const RecipesIndex = (props) => {
    // const [recipes, setRecipes] = useState(null)
    const [error, setError] = useState(false)

    const { msgAlert, input, recipes, setRecipes, searchRecipes } = props
    // console.log("++++++++++++++=", input,recipes, setRecipes)

    console.log('Props in RecipesIndex', props)

    // useEffect( () => {
    //     console.log(props)
    //     getAllRecipes()
    //         .then(res => setRecipes(res.data.recipes))
    //         .catch(err => {
    //             msgAlert({
    //                 heading: 'Error Getting Recipes',
    //                 message: messages.getRecipesFailure,
    //                 variant: 'danger',
    //             })
    //             setError(true)
    //         })
    // }, [])

    useEffect( function ()  {
    async function getMyRecipes () {
        const myRecipes = await getAllRecipes() 
        setRecipes(myRecipes.data.recipes)
        console.log("this is state recipe", recipes)
        console.log("this is my recipes", myRecipes)
    }
    getMyRecipes()
    }, [])
    console.log("this is my recipes", recipes)
    if (error) {
        return <p>Error!</p>
    }

    // If recipes haven't been loaded yet, show a loading message
    if (!recipes) {
        return <LoadingScreen />
    } else if (recipes.length === 0) {
        return <p>No recipes yet, Please check back in a while</p>
    }

    const recipeCards = recipes.map(recipe => (
                <Card
                key={recipe.id}
                style={
                    {
                        backgroundColor: 'rgb(255, 255, 244)',
                        width: '340px',
                        height: '350',
                        borderRadius: '10px',
                        boxShadow: 'box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px',
                        marginLeft: '10px',
                        marginRight: '10px',
                        marginTop: '25px',
                        marginBottom: '5px',
                        border: '2px solid  #D0D0D0'
                    }
                }
                >
                <Link to={`/recipes/${recipe._id}`}
                    style={
                        {

                            textAlign: 'center',
                            textDecoration: 'none',
                            fontSize: '19px',
                            color: 'rgb(56, 55, 55)'
                        }
                    }
                >   
                    <Card.Header>
                        {recipe.recipeName}
                    </Card.Header>
                    <Card.Header>
                        {recipe.recipeType}
                    </Card.Header>
                    <Card.Header
                    style={
                        {
                            fontSize: '15px'
                        }
                    }
                    >
                        Creater Name: {recipe.recipeCreater}
                    </Card.Header>
                </Link>
                <Card.Body  
                style={
                    {
                        // backgroundColor: 'red',
                        maxWidth: '17rem',
                        margin: 'auto'

                    }
                }
                >
                    <Link to={`/recipes/${recipe._id}`}>
                        <img 
                        src={recipe.image} 
                        alt={recipe.recipeName}
                        style={
                                    {
                                        // borderBlockStyle: 'dashed',
                                        maxHeight: '17rem',
                                        maxWidth: '15rem',
                                        padding: '0px',
                                        borderRadius: '4px',
                                        border: '2px solid #C0C0C0',

                                    }
                                }
                        ></img>
                    </Link>
                </Card.Body>
                <Card.Footer>
                    <div 
                    style={
                        {
                            textAlign: 'center',
                        }
                    }>
                        <Link to={`/recipes/${recipe._id}`}
                        style= {
                            {
                                textDecoration: 'none',
                                fontSize: '19px',
                                color: '#cc0052'
                            }
                        }
                        >
                            View recipe
                        </Link>
                    </div>
                </Card.Footer>
            </Card >
    ))

continual for the index page - PART 2


///////////////////////////code block for filter by recipe catagory/////////////////////////////////////
     const filterResults = recipes.filter((recipe) => {
        // recipe.recipeName.toLowerCase().includes(input.toLowerCase()))
        // .map(recipe => (
        // <h1> recipe.recipeName </h1>
        return recipe["recipeType"].includes(searchRecipes)

    })

    const displayRecipes = filterResults.map((filterResult) => {
        return <Card
                key={filterResult.id}
                style={
                    {
                        backgroundColor: 'rgb(255, 255, 244)',
                        width: '340px',
                        height: '350',
                        borderRadius: '10px',
                        boxShadow: 'box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px',
                        marginLeft: '10px',
                        marginRight: '10px',
                        marginTop: '25px',
                        marginBottom: '5px',
                        border: '2px solid  #D0D0D0'
                    }
                }
                >
                <Link to={`/recipes/${filterResult._id}`}
                    style={
                        {

                            textAlign: 'center',
                            textDecoration: 'none',
                            fontSize: '19px',
                            color: 'rgb(56, 55, 55)'
                        }
                    }
                >   
                    <Card.Header>
                        {filterResult.recipeName}
                    </Card.Header>
                    <Card.Header
                    style={
                        {
                            fontSize: '15px'
                        }
                    }
                    >
                        Creater Name: {filterResult.recipeCreater}
                    </Card.Header>
                </Link>
                <Card.Body  
                style={
                    {
                        // backgroundColor: 'red',
                        maxWidth: '17rem',
                        margin: 'auto'

                    }
                }
                >
                    <Link to={`/recipes/${filterResult._id}`}>
                        <img 
                        src={filterResult.image} 
                        alt={filterResult.recipeName}
                        style={
                                    {
                                        // borderBlockStyle: 'dashed',
                                        maxHeight: '17rem',
                                        maxWidth: '15rem',
                                        padding: '0px',
                                        borderRadius: '4px',
                                        border: '2px solid #C0C0C0',

                                    }
                                }
                        ></img>
                    </Link>
                </Card.Body>
                <Card.Footer>
                    <div 
                    style={
                        {
                            textAlign: 'center',
                        }
                    }>
                        <Link to={`/recipes/${filterResult._id}`}
                        style= {
                            {
                                textDecoration: 'none',
                                fontSize: '19px',
                                color: '#cc0052'
                            }
                        }
                        >
                            View recipe
                        </Link>
                    </div>
                </Card.Footer>
            </Card >
        })
        console.log("+++========== show displayRecipes", displayRecipes)

Home.js

// we already have the data
import { useState } from 'react'
import RecipeIndex from './recipes/RecipeIndex'
import ShowJumbotron from './Jumbotron/ShowJumbotron'
// import { getAllRecipes } from '../api/recipes'

const Home = (props) => {
    const [searchInput, setSearchInput] = useState(null)
     const [searchRecipes, setSearchRecipes] = useState(null);
    const [recipes, setRecipes] = useState(null)
    // const { msgAlert, user } = props
    console.log('props in home', props)

    const { msgAlert } = props

    // useEffect( function ()  {
    // async function getMyRecipes () {
    //     const myRecipes = await getAllRecipes() 
    //     setRecipes(myRecipes.data.recipes)
    //     console.log("this is my recipes homepage", myRecipes)
    // }
    // getMyRecipes()
    // }, [])
    return (
        <>
            <div 
            className='jumbotron'>
                <ShowJumbotron 
                setSearchInput = {setSearchInput}
                setSearchRecipes = {setSearchRecipes}
                recipes={recipes}
                />
            </div>
            <RecipeIndex 
            msgAlert={ msgAlert }
            input = {searchInput}
            recipes={recipes}
            setRecipes={setRecipes}
            searchRecipes = {searchRecipes}
            />
        </>
    )
}

export default Home

ShowJumboron component - this is where the icons are found

import React from 'react';
import { FormControl, InputGroup, Button} from 'react-bootstrap';
import './Styles.css'
import { getAllRecipes } from '../../api/recipes'
import { useState } from 'react'
import { FaPizzaSlice } from "react-icons/fa";
import { FaPepperHot } from "react-icons/fa";
import { FaFish} from "react-icons/fa";
import { FaHamburger } from "react-icons/fa";
import { GiNoodles } from "react-icons/gi";
import {NavLink} from 'react-router-dom'
function ShowJumbotron(props) {
    // const [searchInput, setSearchInput] = useState("")
    // function handleSearch(search){
            const {setSearchInput} = props
            const {setSearchRecipes} = props
            console.log("setstate", setSearchInput)

    // const handleChange = (e) => {
    //     recipe.recipeName.toLowerCase().includes(searchInput.toLowerCase())
    // }

  return (
    <div className='my-jumbotron'>
        <div className='jumbotron-text'>
            <h1>Welcome to RecipeTap!</h1>
            <h2>The Endless<span>Recipe </span></h2></div>
        <div className='button-input'>
            <InputGroup className='mb-3'>
                <FormControl
                    placeholder="Search For Recipe Here"
                    aria-label='Meal Search Input'
                    aria-aria-describedby="meal-search-button"
                    onChange={(e) => setSearchInput(e.target.value)}
                />

                <Button variant="danger" id="meal-search-button">
                    Button
                </Button>
            </InputGroup>
        </div>

        {/* this is where we will have the food icons */}
        <div className='react-icons'>
            <NavLink to={"/"}>
                <FaPizzaSlice 
                onClick={(e) => setSearchRecipes(e.target.value)}
                />
                    <h4>Italian</h4>

            </NavLink>
            <NavLink to={"/"}>
                <FaPepperHot 
                onClick={(e) => setSearchRecipes(e.target.value)}
                />
                    <h4>Indian</h4>
            </NavLink>
            <NavLink to={"/"}>
                <FaFish 
                onClick={(e) => setSearchRecipes(e.target.value)}
                />
                    <h4>See Food</h4>

            </NavLink>
            <NavLink to={"/"} >
                <FaHamburger 
                onClick={(e) => setSearchRecipes(e.target.value)}
                />
                    <h4>American</h4>

            </NavLink>
            <NavLink to={"/"} >
                <GiNoodles 
                onClick={(e) => setSearchRecipes(e.target.value)}
                />
                    <h4>Japanese</h4>

            </NavLink>
        </div>
    </div>
  )
}

export default ShowJumbotron

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

TypeError: Cannot read properties of undefined (reading 'includes')

What is your best guess as to the source of the problem?

well for starters, the props and state are defined and passed to the correct components. my best guess would be that either my clicks are not being targeted and passed to the state variable because, every time I click, what I am getting for that variable is null.

What things have you already tried to solve the problem?

I have tried to console.log everything and that is how i saw that i am getting null for my clicks. But the way my onClick function is set up looks right.

Paste a link to your repository here

mattkeane-ga commented 2 years ago

The only line where you're using includes here is this:

return recipe["recipeType"].includes(searchRecipes)

This means that recipe does not have a property named recipeType. I would suggest logging recipe and making sure it looks the way you think it does.

Mahider-Mengiste commented 2 years ago
Screen Shot 2022-08-26 at 2 21 15 PM

Not all recipes have recipe type but some of the recipes that i want to have recipeType have recipeType

mattkeane-ga commented 2 years ago

Uff, I hate it when data is inconsistent like that. You're going to have to test to see if it has that property first then with an if statement.

kestler01 commented 2 years ago

consider optional chaining <myObject>?.<has-key?>

Mahider-Mengiste commented 2 years ago

thanks, I was able to solve the problem. turns out i didn't have recipeType in my seed file.