繁体   English   中英

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'attributes')

[英]Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'attributes')

嘿,我一直收到这个错误,我不确定为什么。 当我检查我的 Rails 控制台时,Recipe 存在,所以我知道它在数据库中的发布,但它没有显示在 DOM 上,所以它显然没有发布在前端。 我不确定为什么属性未定义 postRecipes 但不在 fetchRecipes 中。

编辑:当我刷新页面时,帖子显示。 我如何让它显示而无需刷新页面?

这是我的代码:

const recipesUrl = "http://localhost:3000/api/v1/recipes"

document.addEventListener('DOMContentLoaded', () => {
  fetchRecipes() 

  const createRecipeForm = document.querySelector("#create-recipe-form")

  createRecipeForm.addEventListener("submit", (e) => handleRecipeSubmit(e))
})

// get function
function fetchRecipes() {
  fetch(recipesUrl) // returns a promise
  .then(resp => resp.json()) // parses that promise to json
  .then(recipes => {  // returns an array of recipes
    recipes.data.forEach(recipe => { // itterates over the response and show the data in a div
      const renderRecipe = `
        <div data-id=${recipe.id}>
          <h2>${recipe.attributes.name}</h2>
          <img src=${recipe.attributes.image_url} height="200" width="250">
          <h3>Ingredients:</h3>
          <p>${recipe.attributes.ingredients}</p>
          <h3>Instructions</h3>
          <p>${recipe.attributes.instructions}</p>
          <h3>Category</h3>
          <p>${recipe.attributes.category.name}</p>
          <button data-id="${recipe.id}">Edit</button>
        </div>
      `
      document.querySelector('#recipe-container').innerHTML += renderRecipe
    })
  })
}

function handleRecipeSubmit(e) {
  e.preventDefault()
  const nameInput = document.querySelector('#input-name').value 
  const ingredientsInput = document.querySelector('#input-ingredients').value
  const instructionsInput = document.querySelector('#input-instructions').value 
  const urlInput = document.querySelector('#input-url').value
  const categoryId = parseInt(document.querySelector('#categories').value) // parseInt turns the string into an integer
  postRecipe(nameInput, ingredientsInput, instructionsInput, urlInput, categoryId)
}

function postRecipe(name, ingredients, instructions, image_url, category_id) {
  const bodyData = {name, ingredients, instructions, image_url, category_id}
  fetch(recipesUrl, {
    method: "POST",
    headers: {"Content-Type": 'application/json'},
    body: JSON.stringify(bodyData)
  })
  .then(resp => resp.json())
  .then(recipe => {
    const recipeData = recipe.data
    // render json response
    const fetchRecipe = `
        <div data-id=${recipe.id}>
          <h2>${recipeData.attributes.name}</h2>
          <img src=${recipeData.attributes.image_url} height="200" width="250">
          <h3>Ingredients:</h3>
          <p>${recipeData.attributes.ingredients}</p>
          <h3>Instructions</h3>
          <p>${recipeData.attributes.instructions}</p>
          <h3>Category</h3>
          <p>${recipeData.attributes.category.name}</p>
          <button data-id="${recipeData.id}">Edit</button>
        </div>
      `
      document.querySelector('#recipe-container').innerHTML += fetchRecipe
  })
}

这是我的索引。html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="stylesheets/index.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css">
</head>
<body>
  <div class="form-container">
    <form id="create-recipe-form">
      <h3>Create a New Recipe</h3>
      <input id="input-name" type="text" name="name" value="" placeholder="Recipe name..." class="input-text">
      <br><br>
      <textarea id="input-ingredients" name="ingredients" cols="60" rows="5" placeholder="Recipe ingredients..."></textarea>
      <br><br>
      <textarea id="input-instructions" name="instructions" cols="60" rows="5" placeholder="Recipe instructions..."></textarea>
      <br><br>
      <input id="input-url" type="text" name="image" value="" placeholder="Image url..." class="input-text">
      <br>
      <p>Choose a Category</p>
      <select id="categories" name="categories">
        <option value="1">American</option>
        <option value="2">French</option>
        <option value="3">Italian</option>
        <option value="4">Chinese</option>
        <option value="5">Korean</option>
        <option value="6">Indian</option> 
        <option value="7">Thai</option>
        <option value="8">Mexican</option>
        <option value="9">Vegetarian</option>
        <option value="10">Vegan</option>
      </select>
      <br><br>
      <input id="create-button" type="submit" name="submit" value="Create Recipe" class="submit">
    </form>
  </div>
  <div id="recipe-container">
  </div>
  <div id="footer">
    <a href="#top" id="scroll-back "><i class="fas fa-2x fa-arrow-alt-circle-up"></i></a>
  </div>
</body>
  <script type="text/javascript" src="javascripts/index.js"></script>
</html>

我希望它不仅仅是一个我似乎找不到的错字。

无论如何,这是完整的错误:

index.js:58 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'attributes')
    at index.js:58
(anonymous) @ index.js:58
Promise.then (async)
postRecipe @ index.js:53
handleRecipeSubmit @ index.js:42
(anonymous) @ index.js:8

好问题,我试图回应这个问题并尝试调试它。 根据我的理解,您可以查看如何在此处同步调用fetchRecipes异步调用。

您可以尝试异步/等待

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

您也可以尝试在末尾添加catch以查找确切的错误

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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