0

Okies, So, I am working on a simple recipe collection App, where I have cuisineReducer.js and RecipeReducer.js. enter image description here

and on my admin Dashboard, an admin user is allowed to Create, Delete and Edit any Cuisine groups and also could Create, Delete and Edit Recipes for any Cuisine Group. when user clicks on any cuisine group, it renders all the Recipes in Recipe Panel using Cuisine Id. user can also delete by pressing "x" on Recipe or on Cuisine group. The conflict I need to resolve is when a recipe is deleted,it should be deleted from the ui too without the need of refresh. I dont know how to achieve that. Here is my code.

CuisineReducer.js

import { GET_CUISINES, GET_CUISINE_BY_ID, GET_CUISINE_BY_CATEGORY} from "../actions/types.js"; 
const initialState = { 
      cuisines: [],
      cuisine:{}
};

export default function (state = initialState, action) { 
    switch(action.type) {
        case GET_CUISINES:
             return {
                     ...state,  
                     cuisines:action.payload
                    }; 
        case GET_CUISINE_BY_CATEGORY:
             return {
                     ...state,  
                     cuisines:action.payload
                    }; 
        case GET_CUISINE_BY_ID:
             return {
                     ...state,  
                     cuisine:action.payload
                    }; 
        default:
             return state; 
}

CuisineActions.js

import {  GET_CUISINES, GET_CUISINE_BY_ID} from "./types.js"; 
import axios from 'axios'; 

export const getCuisines = () =>async dispatch => { ... }

export const getCuisineByCategory = (id) =>async dispatch => { 
     const res = await axios.get(`/api/cuisine/${id})
     dispatch({
           type:GET_CUISINES_BY_CATEGORY,
           payload: res.data
     }); 

export const getCuisineById = (id) =>async dispatch => { 
     const res = await axios.get(`/api/cuisine/${id})
     dispatch({
           type:GET_CUISINE_BY_ID,
           payload: res.data
     }); 
}

recipeReducer.js

import { GET_RECIPES, GET_RECIPE_BY_ID, DELETE_RECIPE} from "../actions/types.js"; 

const initialState = { 
      recipes: [],
      recipe:{}
};

export default function (state = initialState, action) { 
    switch(action.type) {
        case GET_RECIPES:
             return {
                     ...state,  
                     recipes:action.payload
                    }; 
        case GET_RECIPE_BY_ID:
             return {
                     ...state,  
                     recipe:action.payload
                    }; 
       case DELETE_RECIPE:
             return {
                     ...state,  
                     recipes:state.recipes.filter(asset => asset.id != action.payload)
                    }; 
        default:
             return state; 
}

RecipeActions.js

import { DELETE_RECIPE} from "./types.js"; 
import axios from 'axios'; 

export const getRecipes = () =>async dispatch => { ... }

export const deleteRecipe = (id) =>async dispatch => { 
     await axios.delete(`/api/recipe/${id})
     dispatch({
           type:GET_RECIPE_BY_ID,
           payload: id
     }); 
}

Admin.js

import React, {Component} from react; 
import {connect} from 'react-redux'; 
import { getCuisineById, getCuisinesByCategory} from '../../actions/cuisineAction.js';
import AdminCuisineList from '../AdminCuisineList.js;
import AdminRecipeList from '../AdminRecipeList.js"; 

Class Admin extends Component {

   componentWillUnmount = () => {
       this.props.clearCuisine(); 
   }

   revealList = category => {
       this.props.getCuisinesByCategory(caegory); 
   }

   revealRecipeList = id => {
     this.props.getCuisineById(id); 
   }

 render () {
  const {cuisines} = this.props; 
  return(
   <div>
    <div>      
     <ul> 
       <li onClick={() => revealList('meal')}>  Meal </li>
       <li onClick={() => revealList('meal')}>   Deserts </li>
       <li onClick={() => revealList('meal')}>   Drinks  </li>
     </ul>    
    </div> 
    { cuisines && 
         cuisines.map(cuisine => ( 
            <AdminCuisineList  label={cuisine.label} recipeHandler={() => this.revealRecipeList(cuisine.id)}} /> 
    ))} 

   { cuisine && cuisine.recipes
         cuisine.recipes.map(recipe => ( 
            <AdminRecipeList  label=recipe.label} cuisineId={recipe.cuisine[0] /> 
    ))} 

  ); 

 }

}

Here is my json data for the calls I am using: getCuisinesByCategory() GET Call Output:

[ 
  "label": "Indian",
  "category": "Meal", 
  "recipes": [ 
      { id: "123", "label": "Chicken Biryani"},
      { id: "124", "label": "Chicken Korma"}, 
      { id:  "125", "label: "Nihari"}, 
      { id: "1244", "label": "Pulao"}, 
      { id: "12321", "label": Pakore"},
      { id: "1232", "label": "Bun Kubab"}     
    ] 
]
Ada_lovelace
  • 637
  • 2
  • 6
  • 18
  • `Admin.js` does not use `recipes` at all, only `cuisine.recipes` which is not defined in the code... have you tried to create an action and reducer for `DELETE_RECIPE_IN_CUISINE`? – Aprillion Apr 09 '19 at 21:44
  • Yeah, In Admin.js I am using recipes nested in cuisine json data. Let me try deleting DELETE_RECIPE_IN_CUISINE – Ada_lovelace Apr 09 '19 at 22:08

1 Answers1

0

It looks like you handle deleting recipes in your reducer - you are using the wrong action for when you delete your recipe. You need to use your DELETE_RECIPE action type. You are using GET_RECIPE_BY_ID

export const deleteRecipe = (id) =>async dispatch => { 
 await axios.delete(`/api/recipe/${id})
 dispatch({
       type:DELETE_RECIPE,
       payload: id
 }); 
}
pizzarob
  • 11,711
  • 6
  • 48
  • 69