Stitch
Stitch

Reputation: 213

Redux objects is being submited empty on submission

I am having an issue when I submit my form my object is being submitted empty when , and I confirmed this in the redux dev-tool as well. When I submit my form, a card is supposed to appear on the DOM with the info I entered into the form on it, or in react terms with the info passed down to the props of that component. Well when I submit the info is empty, and my redux dev tool is showing that object is empty on submission.

Here is my POST action

export const postRecipes = (recipe) => {
  
    const BASE_URL = `http://localhost:3001`
    const RECIPES_URL =`${BASE_URL}/recipes`
    const config = {
        method: "POST",
        body:JSON.stringify(recipe),
        headers: {
        "Accept": "application/json",
        "Content-type": "application/json"
     }
    }

    return (dispatch) => {
      
      fetch(RECIPES_URL,config)
        .then(response =>{ response.json()})
        .then(recipe => { dispatch({ type: 'ADD_RECIPE', payload: recipe })
        
    })
    .catch((error) => console.log.error(error))
       
        
    };

    
    
  }

Edit: added GET action for my retrieving my recipes saved to database

export const getRecipes = () => {
  
    const BASE_URL = `http://localhost:3001`
    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 })});
       
        
    };

    
    
  }

Here is my reducer action type for Adding the object(Hopefully I worded this correctly)

case 'START_ADDING_RECIPE':
            return{
                ...state,
                loading:true
            }

        case 'ADD_RECIPE':
            const recipe = {
                name: action.name,
                ingredients: action.ingredients,
                chef_name: action.chef_name,
                origin: action.origin,
                instructions: action.instructions,
                category_id: action.category_id
                
            }
        

Edit: adding reducers for request see current state of my recipes

case 'START_FETCHING_RECIPES_REQUEST':
            return {
                ...state,
            recipes: [...state.recipes],
            loading: true
        }
        case 'GET_RECIPES':
            return {
                ...state, recipes: action.recipes,
                loading: false
            }

Edit: My mapDispatchToProps and mapDispatchToState functions

const mapStateToProps = state =>{
    return{
        recipes: state.recipes,
        loading: state.loading

    }
}


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

Edit:Including my created store

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import manageRecipes from './reducers/manageRecipes';
import 'bootstrap/dist/css/bootstrap.min.css';
import { composeWithDevTools } from 'redux-devtools-extension'

const composeEnhancer = composeWithDevTools(applyMiddleware(thunk))
const store = createStore(manageRecipes,composeEnhancer)

ReactDOM.render(
  
    <Provider store={store}>
    <App />
    </Provider>,
   
  document.getElementById('root')
);

Edit: I believe I added a few things in this code Here is the event handler that goes off when a user interacts with the submit button

import React, { Component } from 'react'
import Select from 'react-select'
import axios from 'axios'
import '../index.css'



class RecipeInput extends Component{
    constructor(props){
        super(props)
        this.state = {
            
            category_id: [],
            name:'',
            ingredients: '',
            chef_name: '',
            origin: '',
            instructions:''
            
        }
        

        
    }


      

    
    async getOptions(){
        const BASE_URL = `http://localhost:3001`
        const CATEGORIES_URL =`${BASE_URL}/categories`
        const res = await axios.get(CATEGORIES_URL)
        const data = res.data

        const options = data.map(d => ({
           
            
           
            'label' : d.category,
            'id' : d.id

            
        }))

        this.setState({category_id: options})
    }

    

    handleNameChange = (event) =>{
        this.setState({name:event.target.value})
    }

    handleInsChange = (event) =>{
        this.setState({instructions:event.target.value})
    }

    handleIngChange = (event) =>{
        this.setState({ingredients:event.target.value})
    }

    handleChefChange = (event) =>{
        this.setState({chef_name:event.target.value})
    }

    handleOriginChange = (event) =>{
        this.setState({origin:event.target.value})
    }

    handleChange = (event) =>{
        
        this.setState({category_id:event.id})
    }

    componentDidMount(){
        this.getOptions()
    }


    handleSubmit = (event) =>{
        alert(this.state.name + 'was set!')
        event.preventDefault();
        this.props.postRecipes(this.state)
        this.setState({
        name:'',
        ingredients: '',
        chef_name: '',
        origin: '',
        instructions: ''
       })
     
     
    }

    

    
    
        

    render(){
       let dropdown = 'form-select form-select-sm'
  
        return(
            <div>
                
                <form onSubmit={this.handleSubmit}>
                    <Select options={this.state.category_id} onChange={this.handleChange} className={dropdown}/>
                    <div>
                    <label for='name'>Recipe Name:</label>
                    <input  className ="form-control" type='text' value={this.state.name} onChange={this.handleNameChange} />
                    </div>
                    <div>
                    <label for='name'>Country Origin:</label>
                    <input className ="form-control" type='text' value={this.state.origin} onChange={this.handleOriginChange} />
                    </div>
                    <div>
                    <label for='name'>Chef Name:</label>
                    
                    <input className ="form-control" type='text' value={this.state.chef_name} onChange={this.handleChefChange} />
                    </div>
                    <div>
                    <label for='name'>Ingredients:</label>
                    <textarea className ="form-control" cols="30" rows="5" type='text' value={this.state.ingredients} onChange={this.handleIngChange} />
                    
                    <label for='name'>Instructions:</label>
                    <textarea className ="form-control" cols="30" rows="5" type='text' value={this.state.instructions} onChange={this.handleInsChange} />
                    </div>
                    <input value='submit' type='submit'/>
                </form>
                
            </div>
        )
    }


 


}

export default RecipeInput

I feel like this is in my post action somewhere but not sure where, how can I correct this?

Upvotes: 2

Views: 98

Answers (1)

Yash Digant Joshi
Yash Digant Joshi

Reputation: 75

The way I am understanding this, I could be wrong but here is my understanding,

In you RecipeInput class, you're calling handleSubmit(). In that function you're calling out to postRecipes() using this.state.

Where do you set the this.state variable after initializing it to the following?

this.state = {
            category_id: [],
            name:'',
            ingredients: '',
            chef_name: '',
            origin: '',
            instructions:''
            
        }

So the post request in fetch(RECIPES_URL,config), will send an empty object. So to change this, you will have to set this.states before calling the postRecipes() function.

Upvotes: 1

Related Questions