name.forEach не является функцией после нажатия кнопки - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь редактировать / обновлять текущие данные, используя атрибут contenteditable, который я успешно включил в клик. Моя клавиша ввода позволяет отправлять данные. Однако console.log читает, что был сделан запрос PUT для определенного элемента списка, но без обновления «title» или «isbn» вместе с ним.

Другая важная проблема заключается в том, что мой console.log показывает books.forEach is not a function, и я понятия не имею, почему это так, поскольку код внутри этой функции обрабатывается.

HTML (элементы 'li' сгенерированы исключительно JS с запросом POST)

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

UPDATE

Я добавил следующее в мой код. Это, кажется, отображает мои элементы базы данных в виде массива в журнале. Но сейчас у меня похожая проблема с 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, а вторая - моя попытка преобразовать каждый объект в массив.

См. Изображение

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вы должны убедиться, что ваша переменная books действительно содержит массив после разбора.

В качестве альтернативы, но это не имеет смысла, просто для решения проблемы "books.forEach is not function", вы можете использовать Object.assign([], this.response);. Чтобы убедиться, что books будет содержать массив, вы заключаете его в попытку и создаете что-то вроде этого:

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", "'", "}"]

В результате вам придется проверять book в вашем forEach обратном вызове, если он правильный:

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

Это снова предоставит вам еще одно исключение для обработки. Или вам придется использовать традиционный цикл for, поскольку вы не можете замкнуть Array.forEach с разрывом .

TLDR: убедитесь, что books всегда содержит массив.

0 голосов
/ 10 января 2019

Вы получаете книги из JSON.parse (), что означает, что книги - это объект, а не массив. forEach - это метод массива. Попробуйте консольные журналы и найдите в нем массив.

...