Stitch
Stitch

Reputation: 213

Props not displaying from fetch call

I am trying to display recipes and not sure if I have this setup correctly. I am pulling recipes from a rails api via get fetch request. At the moment nothing is displaying.

Here is my recipe container:

import React, { Component } from 'react'
import RecipeList from '../components/RecipeList'
import RecipeInput from '../components/RecipeInput'
import { connect } from 'react-redux'
import { postRecipes } from '../actions/postRecipes.js'
import { getRecipes } from '../actions/getRecipes'


class RecipeContainer extends Component{
    constructor(props){
        super(props)
    }

    componentDidMount(){
        getRecipes()
      }
    

    render(){
        return (
            <div>
               <RecipeInput postRecipes={this.props.postRecipes} /> 
               <RecipeList getRecipes={this.props.recipes} />
            </div>
        )
    }

    

}

const mapStateToProps = state =>({
   recipes: state.recipes
})


const mapDispatchToProps = dispatch =>{
    return{
    postRecipes: (recipe) => dispatch(postRecipes(recipe)),
    getRecipes: () => dispatch(getRecipes())
    // deleteRecipe: id => dispatch({type: 'Delete_Recipe', id})
    }
}



export default connect(mapStateToProps,mapDispatchToProps)(RecipeContainer)

Here is my get request....notice that I am returning my Recipe component here.

export const getRecipes = () => {
  
    const BASE_URL = `http://localhost:10524`
    const RECIPES_URL =`${BASE_URL}/recipes`

    return (dispatch) => {
      dispatch({ type: 'START_FETCHING_RECIPES_REQUEST' });
      fetch(RECIPES_URL)
        .then(response =>{ return response.json()})
        .then(recipes => dispatch({ type: 'Get_Recipes', recipes }));
    };
    
  }

This is where I am trying to render the Recipe component from the get request

import React, {Component} from 'react';
// import { getRecipes } from '../actions/getRecipes.js';
import Recipe from './Recipe.js'

class RecipeList extends Component {

// componentDidMount(){
//   getRecipes()
// }

render() {
   
   return (
    
  
    <div>
     {this.props.recipes.map(recipe => (<Recipe recipe={recipe} key={recipe.id} />))}
    </div>
   )
    
  }
}

export default RecipeList;

Edit: Added reducer

switch(action.type){
        case 'Add_Recipe':
            const recipe = {
                
                name: action.name,
                ingredients: action.ingredients,
                chef_name: action.chef_name,
                origin: action.origin,
                category: action.category
                
            }

            return{
                ...state,
                recipes: [...state.recipes, recipe],
            }
          
          case 'START_FETCHING_RECIPES_REQUEST':
            return {
                ...state,
            recipes: [...state.recipes],
            requesting: true
        }
        case 'Get_Recipes':
            return {
                ...state, recipes: action.recipes,
                requesting: false
            }
        

          default:
            return state
        
    }
}



How can I correct this to make it work?

Upvotes: 1

Views: 129

Answers (2)

Stitch
Stitch

Reputation: 213

The actual solution to this was I needed to have an explicit return in my mapStateToProp function.

Eg.

const mapStateToProp = state =>{
  return {
         recipes: state.recipes
    }
}

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 203408

Issue

You are not passing the recipes to the RecipeList component that were fetched and presumably stored in state, and fed back to the UI via RecipeContainer.

Solution

Pass the recipe state from RecipeContainer to RecipeList as a prop. and then render/map the recipes from props.

RecipeContainer

class RecipeContainer extends Component{
  componentDidMount() {
    getRecipes();
  }
    
  render() {
    return (
      <div>
        <RecipeInput postRecipes={this.props.postRecipes} /> 
        <RecipeList getRecipes={this.props.recipes} /> // <-- pass recipe state
      </div>
    )
  }
}

const mapStateToProps = state => ({
  recipes: state.recipes,
});

const mapDispatchToProps = dispatch => {
  return {
    postRecipes: (recipe) => dispatch(postRecipes(recipe)),
    getRecipes: () => dispatch(getRecipes())
  }
};

RecipeList

class RecipeList extends Component { 
  render() {
    const { recipes } = this.props;
    return (
      <div>
       {recipes.map(recipe => (
         <Recipe recipe={recipe} key={recipe.id} />
       ))}
      </div>
     );
  }
}

Upvotes: 2

Related Questions