Search code examples
jsonreactjsgetfetch

issues with fetching Json in react


I apologise as this is probably either very basic or i've done something compeltely wrong. I'm brand new to React, and coding in general, and I'm trying to make a React app that shows the recipes im using on cards. The cards in turn should be searchable and dynamic, dissapearing if they don't match etc.

This is my app.js file, that when run, it just brings up my custom "Loading" screen without data. Where have I messed up on this?

import React, {Component} from 'react';
import CardList from './CardList';
import SearchBox from './SearchBox';
import Scroll from "./Scroll";
import "./App.css"



class App extends Component {
    constructor() {
        super()
        this.state = {
            recipes: [],
            searchfield: "",
        }
    }

    componentDidMount() {
        fetch("./recipedata.json")
        .then(response => { return response.json();})
        .then(recipedata => {this.setState({recipes: recipedata})});
    }

    onSearchChange= (event) =>{
    this.setState({searchfield: event.target.value})
    
    }

    render() {
        const filteredRecipe = this.state.recipes.filter(recipes =>{
            return recipes.name.toLowerCase().includes(this.state.searchfield.toLowerCase());
        })
        if (this.state.recipes.length === 0) {
            return <h1 class="f1 tc">Loading</h1>
        } else {
        return(
            <div className="tc">
            <h1 className="f1">Recipes</h1>
            <SearchBox searchChange={this.onSearchChange} />
            <Scroll>
            <CardList recipe={filteredRecipe}/>
            </Scroll>
            </div>
        )
         }

    }
        
}

export default App

Thanks in advance

edit: I have been asked to post the contents of recipedata.json:

    [
    {
        "id" : 1,
        "name" : "Carrot cake",
        "type" : "sweet",
        "author" : "Grandma",
        "link" : "recipes/carrotcake.html"
    },
    {
        "id" : 2,
        "name" : "Spicy chicken pitta filling",
        "type" : "savoury",
        "author" : "Grandma",
        "link" : "recipes/chickenpitta.html"
    },
    {
        "id" : 3,
        "name" : "Mushroom ham and chicken crusty puff pies",
        "type" : "savoury",
        "author" : "Grandma",
        "link" : "recipes/crustypuff.html"
    },
    {
        "id" : 4,
        "name" : "Sweet potato pumpkin seed rolls",
        "type" : "savoury",
        "author" : "Grandma",
        "link" : "recipes/sweetpotrolls.html"
    },
    {
        "id": 5,
        "name": "Wild mushroom wafer",
        "type": "savoury",
        "author" : "Grandma",
        "link": "recipes/mushroomwafer.html"
    },
    {
        "id": 6,
        "name": "Piri Piri chicken sauce",
        "type": "savoury",
        "author": "Grandma",
        "link": "recipes/piriRecipe.html"
    },
    {
        "id": 7,
        "name": "Chicken Liver Pate'",
        "type": "savoury",
        "author": "Grandma",
        "link": "recipes/pate.html"
    },
    {
        "id": 8,
        "name": "Creamy mushroom pasta",
        "type": "savoury",
        "author": "Grandma",
        "link": "recipes/mushroompasta.html"
    },
    {
        "id": 9,
        "name": "Cheesey garlic bread",
        "type": "savoury",
        "author": "Grandma",
        "link": "recipes/gbread.html"
    },
    {
        "id": 10,
        "name": "Mini quiches",
        "type": "savoury",
        "author": "Grandma",
        "link": "recipes/miniquiche.html"
    },
    {
        "id": 11,
        "name": "Sticky lemon ginger cake",
        "type": "sweet",
        "author": "Grandma",
        "link": "recipes/stickyrecipe.html"
    },
    {
        "id": 12,
        "name": "Sticky toffee pudding",
        "type": "sweet",
        "author": "Grandma",
        "link": "recipes/stickytoffee.html"
    },
    {
        "id": 12,
        "name": "Iced cream buns",
        "type": "sweet",
        "author": "Grandma",
        "link": "recipes/icedcreambuns.html"
    },
    {
        "id": 13,
        "name": "Pineapple Cake",
        "type": "sweet",
        "author": "Grandma",
        "link": "recipes/pineapplecake.html"
    }
]

Edit 2:

Thanks for your help all, I've now fixed the app.js file and the Json is being returned. I'm now faced with this error in my CardList.js component:

TypeError: Cannot read property 'map' of undefined
CardList
C:/Users/mattj/OneDrive/Desktop/coding/gmcb-react-app/src/CardList.js:5
  2 | import Card from './Card.js';
  3 | 
  4 | const CardList = ({recipes}) => {
> 5 |    return <div>
  6 |       {recipes.map((recipedata, i) => {
  7 |         return( 
  8 |         <Card 

code:

    import React from 'react';
import Card from './Card.js';

const CardList = ({recipes}) => {
   return <div>
      {recipes.map((recipedata, i) => {
        return( 
        <Card 
        key={i} 
        id={recipes[i].id} 
        name={recipes[i].name} /> 
        )
    })}
    </div>
}

export default CardList

What have I messed up here?


Solution

  • Regarding issue #2 you posted it is really tough to say, however I think you are overcomplicating things with your card list. You should simply pass an array of filtered recipes to your component.

    Your card list component you should just pass an entire recipe option to the component instead of trying to pass specific props. If in the future you add more keys to each recipe object you wont have to adjust your card list

    const CardList = ({recipes}) => {
        return (
            <div>
                {
                    recipes.map(recipe => {
                        return <Card recipe={recipe} key={recipe.id} />
                    })
                }
            </div>
        )
    }
    

    Inside your card component you can destructure the keys off the recipe object

    const Card = ({recipe}) => {
        return (
            <div>
                <h3>{recipe.name}</h3>
                <p>{recipe.type} - {recipe.author}</p>
                <hr />
            </div>
        )
    }
    

    I made you a code sandbox, I used React Hooks and a mockAxios call in order to fake what a server would do and so you have some code for if you want to call an API in the future. https://codesandbox.io/s/broken-glitter-4wb61?file=/src/App.js