我收到一个错误:无法读取未定义的属性“ push”

时间:2020-09-21 11:03:17

标签: javascript

我目前正在一个个人项目上,创建一个食谱应用程序。当我启动开发服务器时,出现错误:Ingredients.js:26 Uncaught TypeError:无法读取未定义的属性“ push”

我认为,配方成分存在问题,但是当我尝试对其进行调整时,我仍然无法解决。任何人都可以看一下我的源代码,一个文件名为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 }

如果我按以下方式更改功能

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()
}

然后我又遇到另一个错误: 未捕获的ReferenceError:配方未定义 在createIngredients(ingredients.js:24) 在HTMLFormElement。 (edit.js:29)

但是我不明白为什么,因为我将recipes.js导入了Ingredients.js,所以应该在那时定义它。

下面是recipes.js代码

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 }

1 个答案:

答案 0 :(得分:0)

错误Cannot read property 'push' of undefined表示您ingredients的属性recipeundefined

可以由您之前使用recipes.find(() => ...)的代码来解释

Array.prototype.find()的文档中所述,它返回:

满足提供的测试功能的数组中第一个元素的值。否则,返回undefined。

您必须首先检查是否已找到您的食谱。

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()