【问题标题】:name.forEach is not a function after button is clicked单击按钮后,name.forEach 不是函数
【发布时间】:2019-06-05 01:22:47
【问题描述】:

我正在尝试使用已成功启用 onclick 的 contenteditable 属性编辑/更新当前数据。我的“输入”键允许提交数据。但是,console.log 读取到已针对特定列表项发出了 PUT 请求,但没有随之更新“标题”或“isbn”。

另一个突出的问题是我的console.log 显示books.forEach is not a function,我不知道为什么会这样,因为该函数内的代码已被处理。

HTML('li' 项目完全是通过 POST 请求由 JS 生成的)

<div id="divShowBooks">
  <li id="[object HTMLParagraphElement]">
    <p id="24" name="anID" placeholder="24">1</p>
    <p id="TEST" name="aTitle" placeholder="TEST">TEST</p>
    <p id="12345" name="anISBN" placeholder="12345" contenteditable="true">12345</p>
    <button>Delete</button>
  </li>
</div>

JavaScript

var book_list = document.querySelector('#divShowBooks');

    book_list.innerHTML = "";

    var books = JSON.parse(this.response);

    books.forEach(function (book) {

        // Text information to be displayed per item
        var id = document.createElement('p');
        id.type = 'text';
        id.innerHTML = book.id;
        var title = document.createElement('p');
        title.type = 'text';
        title.innerHTML = book.title;

        var isbn = document.createElement('p');
        isbn.type = 'text';
        isbn.innerHTML = book.isbn;

        // Defining the element that will be created as a list item
        var book_item = document.createElement('li');

        // Displays id, title and ISBN of the books from the database
        book_item.appendChild(id);
        book_item.appendChild(title);
        book_item.appendChild(isbn);

        // Creates an ID attribute per list item
        book_item.setAttribute("id", id)

        // Assigns attributes to p items within book items
        id.setAttribute("id", book.id)
        title.setAttribute("id", book.title)
        isbn.setAttribute("id", book.isbn)

        // Adding a generic name to these elements
        id.setAttribute("name", "anID")
        title.setAttribute("name", "aTitle")
        isbn.setAttribute("name", "anISBN")


        title.addEventListener('click', function (e) {
            e.preventDefault();
            title.contentEditable = "true";
            title.setAttribute("contenteditable", true);
            title.addEventListener('keypress', function (e) {
                if (e.keyCode === 13) {
                    e.preventDefault();
                    xhttp.open("PUT", books_url + '/' + book.id, true);
                    var editTitle = new FormData() /
                        editTitle.append("title", document.getElementsByName("aTitle")[0].value)
                    xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
                    xhttp.send(); //
                }
            });
        });

更新

我已将以下内容添加到我的代码中。这似乎将我的数据库项目显示为日志中的数组。但是,我现在遇到了与Uncaught TypeError: JSON.parse(...).map is not a function 类似的问题:

var params = [
    id = 'id',
    title = 'title',
    isbn = 'isbn',
    createdAt = 'createdAt',
    updatedAt = 'updatedAt'
];

var books = JSON.parse(this.response).map(function(obj) {
    return params.map(function(key) {
        return obj[key];
    });
});
console.log(books);

更新 2

这是我在 console.log 中收到的图像。第一部分显示原始 JSON 内容,第二部分是我尝试将每个对象转换为数组。

See Image

【问题讨论】:

  • 您是否尝试转储 books 变量以验证它是否包含数组 (console.log(books);)?
  • .forEach() 是一个数组方法。你确定你的变量是一个数组吗?
  • 您的代码有一些不平衡的括号。你能修复它并使用适当的缩进以便我们可以看到结构吗?
  • 我在 console.log 中检查过,它似乎没有作为数组处理。我将如何适当地改变这一点?
  • @AelaHuntress 您应该包含您控制台记录的书籍的实际数据结构,以便我们了解我们正在查看的内容

标签: javascript function xmlhttprequest submit contenteditable


【解决方案1】:

您必须确保您的books 变量在解析后实际上包含一个数组。

或者,但这没有意义,只是为了解决“books.forEach 不是函数”问题,您可以使用Object.assign([], this.response);。为确保 books 包含一个数组,请将其包装在 try catch 中并进行如下操作:

var books = [];

try {
    books = Object.assign([], this.response);

} catch (error) {
    books = [];
}

books.forEach 会一直工作,但你必须小心,因为可能会发生这样的事情:

var myStringObject = "{'myProperty':'value'}";
var myArray = Object.assign([], myStringObject );
//myArray value is ["{", "'", "myProperty", "'", ":", "'", "value", "'", "}"]

如果正确,您必须检查forEach 回调中的book

//at the topmost of your forEach callback
if(!book.id) throw BreakException; //A simple break will not work on forEach

这将再次让您处理另一个异常。或者让你不得不使用传统的for循环,因为你cannot short circuit Array.forEach with a break

TLDR:确保books 始终包含一个数组。

【讨论】:

    【解决方案2】:

    您从 JSON.parse() 获取书籍,这意味着书籍是一个对象而不是数组。 forEach 是一个数组方法。 尝试控制台日志记录书并在其中查找数组。

    【讨论】:

    • 结果显示所有书籍都是对象。解决此问题的最佳方法是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 2022-11-14
    相关资源
    最近更新 更多