简体   繁体   中英

I am getting an error: Cannot read property 'push' of undefined

I am currently working on a personal project creating a recipe-app. when I launch a dev-server, I am getting an error: ingredients.js:26 Uncaught TypeError: Cannot read property 'push' of undefined

I think, there is a problem with recipe.ingredients but when I tried to tweak it, I still couldn't solve it. Could anyone please have a look at my source code, a file is called ingredients.js

 import uuidv4 from 'uuid/v4' import { getRecipe, saveRecipe } from './recipes' const createIngredients = (recipeId, text) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) recipe.ingredients.push({ id: uuidv4(), text, completed: false }) saveRecipe() } const removeIngredients = (id, recipeId) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients const ingredientIndex = ingredients.find((ingredient) => ingredient.id === id) if (ingredientIndex > -1) { ingredients.splice(ingredientIndex, 1) } } // Toggle the completed value for a given ingredient const toggleIngredients = (id, recipeId) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients const ingredient = ingredients.find((ingredient) => ingredient.id === id) if (ingredient) { ingredient.completed = !ingredient.completed saveRecipe() } } // render the ingredients const renderIngredients = (recipeId) => { const ingredientEl = document.querySelector('#ingredients') const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients ingredientEl.innerHTML = '' if (ingredients.length > 0) { ingredients.forEach((ingredient) => { ingredientEl.appendChild(generateIngredientDOM(ingredient)) }) } else { const messageEl = document.createElement('p') messageEl.classList.add('empty-message') messageEl.textContent = 'No ingredients to show' ingredientEl.appendChild(messageEl) } saveRecipe() } const generateIngredientDOM = (ingredient) => { const ingredientEl = document.createElement('label') const containerEl = document.createElement('div') const ingredientText = document.createElement('span') const checkbox = document.createElement('input') const removeButton = document.createElement('button') const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id) // Setup ingredient checkbox checkbox.setAttribute('type', 'checkbox') checkbox.checked = ingredient.completed containerEl.appendChild(checkbox) checkbox.addEventListener('change', () => { toggleIngredients(ingredient.id, recipe.id) renderIngredients(recipe.id) }) // Setup the ingredient text ingredientText.textContent = ingredient.text containerEl.appendChild(ingredientText) // Setup container ingredientEl.classList.add('list-item') containerEl.classList.add('list-item__container') ingredientEl.appendChild(containerEl) // Setup the remove button removeButton.textContent = 'remove' removeButton.classList.add('button', 'button--text') ingredientEl.appendChild(removeButton) removeButton.addEventListener('click', () => { removeIngredients(ingredient.id, recipe.id) renderIngredients(recipe.id) }) return ingredientEl } const generateSummaryDOM = (incompleteIngredients) => { const summary = document.createElement('h2') const plural_pronoun = incompleteIngredients.length <= 1 ? 'is' : 'are' const plural = incompleteIngredients.length <= 1 ? '' : 's' summary.classList.add('list-title') summary.textContent = `There ${plural_pronoun} ${incompleteIngredients.length} ingredient${plural} missing` return summary } export { createIngredients, renderIngredients, generateSummaryDOM }

if I change the function as following

 const createIngredients = (recipeId, text) => { const recipe = recipes.find((recipe) => recipe.id === recipeId); // Returns undefined if(recipe) recipe.ingredients.push({ id: uuidv4(), text, completed: false }) else console.log("Recipe not found"); saveRecipe() }

then I am getting another error: Uncaught ReferenceError: recipes is not defined at createIngredients (ingredients.js:24) at HTMLFormElement. (edit.js:29)

But I don't understand why, since I imported recipes.js to ingredients.js, so it should be defined then.

below is recipes.js code

 import uuidv4 from 'uuid/v4' let recipes = [] // Get the saved data and return the value found fot the key 'recipes' in localStorage.getItem('recipes') const loadRecipe = () => { const recipesJSON = localStorage.getItem('recipes') try { return recipesJSON ? JSON.parse(recipesJSON) : [] } catch (e) { return [] } } // Save the recipes to localStorage const saveRecipe = () => { localStorage.setItem('recipes', JSON.stringify(recipes)) } const getRecipe = () => recipes const createRecipe = () => { const id = uuidv4() recipes.push({ id: id, title: '', body: '', ingredients: [] }) saveRecipe() return id } const removeRecipe = (id) => { const recipeIndex = recipes.findIndex((recipe) => recipe.id === id) if (recipeIndex > -1) { recipes.splice(recipeIndex, 1) saveRecipe() } } const updateRecipe = (id, updates) => { const recipe = recipes.find((recipe) => recipe.id === id) if (!recipe) { return } if (typeof updates.title === 'string') { recipe.title = updates.title } if (typeof updates.body === 'string') { recipe.body = updates.body } saveRecipe() return recipe } recipes = loadRecipe() export { getRecipe, createRecipe, removeRecipe, updateRecipe, saveRecipe }

I am currently working on a personal project creating a recipe-app. when I launch a dev-server, I am getting an error: ingredients.js:26 Uncaught TypeError: Cannot read property 'push' of undefined

I think, there is a problem with recipe.ingredients but when I tried to tweak it, I still couldn't solve it. Could anyone please have a look at my source code, a file is called ingredients.js

 import uuidv4 from 'uuid/v4' import { getRecipe, saveRecipe } from './recipes' const createIngredients = (recipeId, text) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) recipe.ingredients.push({ id: uuidv4(), text, completed: false }) saveRecipe() } const removeIngredients = (id, recipeId) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients const ingredientIndex = ingredients.find((ingredient) => ingredient.id === id) if (ingredientIndex > -1) { ingredients.splice(ingredientIndex, 1) } } // Toggle the completed value for a given ingredient const toggleIngredients = (id, recipeId) => { const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients const ingredient = ingredients.find((ingredient) => ingredient.id === id) if (ingredient) { ingredient.completed = !ingredient.completed saveRecipe() } } // render the ingredients const renderIngredients = (recipeId) => { const ingredientEl = document.querySelector('#ingredients') const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id === recipeId) const ingredients = recipe.ingredients ingredientEl.innerHTML = '' if (ingredients.length > 0) { ingredients.forEach((ingredient) => { ingredientEl.appendChild(generateIngredientDOM(ingredient)) }) } else { const messageEl = document.createElement('p') messageEl.classList.add('empty-message') messageEl.textContent = 'No ingredients to show' ingredientEl.appendChild(messageEl) } saveRecipe() } const generateIngredientDOM = (ingredient) => { const ingredientEl = document.createElement('label') const containerEl = document.createElement('div') const ingredientText = document.createElement('span') const checkbox = document.createElement('input') const removeButton = document.createElement('button') const recipes = getRecipe() const recipe = recipes.find((recipe) => recipe.id) // Setup ingredient checkbox checkbox.setAttribute('type', 'checkbox') checkbox.checked = ingredient.completed containerEl.appendChild(checkbox) checkbox.addEventListener('change', () => { toggleIngredients(ingredient.id, recipe.id) renderIngredients(recipe.id) }) // Setup the ingredient text ingredientText.textContent = ingredient.text containerEl.appendChild(ingredientText) // Setup container ingredientEl.classList.add('list-item') containerEl.classList.add('list-item__container') ingredientEl.appendChild(containerEl) // Setup the remove button removeButton.textContent = 'remove' removeButton.classList.add('button', 'button--text') ingredientEl.appendChild(removeButton) removeButton.addEventListener('click', () => { removeIngredients(ingredient.id, recipe.id) renderIngredients(recipe.id) }) return ingredientEl } const generateSummaryDOM = (incompleteIngredients) => { const summary = document.createElement('h2') const plural_pronoun = incompleteIngredients.length <= 1 ? 'is' : 'are' const plural = incompleteIngredients.length <= 1 ? '' : 's' summary.classList.add('list-title') summary.textContent = `There ${plural_pronoun} ${incompleteIngredients.length} ingredient${plural} missing` return summary } export { createIngredients, renderIngredients, generateSummaryDOM }

if I change the function as following

 const createIngredients = (recipeId, text) => { const recipe = recipes.find((recipe) => recipe.id === recipeId); // Returns undefined if(recipe) recipe.ingredients.push({ id: uuidv4(), text, completed: false }) else console.log("Recipe not found"); saveRecipe() }

then I am getting another error: Uncaught ReferenceError: recipes is not defined at createIngredients (ingredients.js:24) at HTMLFormElement. (edit.js:29)

But I don't understand why, since I imported recipes.js to ingredients.js, so it should be defined then.

below is recipes.js code

 import uuidv4 from 'uuid/v4' let recipes = [] // Get the saved data and return the value found fot the key 'recipes' in localStorage.getItem('recipes') const loadRecipe = () => { const recipesJSON = localStorage.getItem('recipes') try { return recipesJSON ? JSON.parse(recipesJSON) : [] } catch (e) { return [] } } // Save the recipes to localStorage const saveRecipe = () => { localStorage.setItem('recipes', JSON.stringify(recipes)) } const getRecipe = () => recipes const createRecipe = () => { const id = uuidv4() recipes.push({ id: id, title: '', body: '', ingredients: [] }) saveRecipe() return id } const removeRecipe = (id) => { const recipeIndex = recipes.findIndex((recipe) => recipe.id === id) if (recipeIndex > -1) { recipes.splice(recipeIndex, 1) saveRecipe() } } const updateRecipe = (id, updates) => { const recipe = recipes.find((recipe) => recipe.id === id) if (!recipe) { return } if (typeof updates.title === 'string') { recipe.title = updates.title } if (typeof updates.body === 'string') { recipe.body = updates.body } saveRecipe() return recipe } recipes = loadRecipe() export { getRecipe, createRecipe, removeRecipe, updateRecipe, saveRecipe }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM