简体   繁体   中英

Why is my array.map() not returning a new value when using spread operator?

I want a user to be able to put his info about their book and push it into the library. I can do this when it comes to display but I want to have it saved as a new object in javascript. A new array 'newBooks' that I created don't return a new value, it stays the same even though I used spread operator which is supposed to change the value. Could someone tell me what's going on?

 const booksContainer = document.querySelector('.booksContainer'); const buttonNewBook = document.querySelector('.buttonNewBook'); const buttonConfirm = document.querySelector('.confirmBook') const inputContainer = document.querySelector('.addNewBook'); buttonNewBook.addEventListener('click', () => { if (inputContainer.style.display === 'none') { inputContainer.style.display = 'flex' } else { inputContainer.style.display = 'none' } if (buttonConfirm.style.display === 'none') { buttonConfirm.style.display = 'inline' } else { buttonConfirm.style.display = 'none' } }); const books = [ { id: 1, imageUrl: '', title: 'Title:', author: 'Author:', pages: 'Pages:' }, { id: 5, imageUrl: '', id: 6, title: 'Title:', id: 7, author: 'Author:', id: 8, pages: 'Pages:' }, { id: 9, imageUrl: '', id: 10, title: 'Title:', id: 11, author: 'Author:', id: 12, pages: 'Pages:' }, { id: 13, imageUrl: '', id: 14, title: 'Title:', id: 15, author: 'Author:', id: 16, pages: 'Pages:' } ] books.forEach((book, index) => { let booksDisplay = document.createElement('div') booksDisplay.setAttribute('class', 'booksDisplay') booksContainer.appendChild(booksDisplay) let booksDisplayImage = document.createElement('img'); booksDisplayImage.src = (`${book.imageUrl}`) booksDisplayImage.setAttribute('class', 'booksImage'); booksDisplay.appendChild(booksDisplayImage); let imageContainer = document.createElement('div') imageContainer.setAttribute('class', 'imageContainer'); booksDisplay.appendChild(imageContainer); imageContainer.appendChild(booksDisplayImage) let booksDisplayTextTitle = document.createElement('p'); booksDisplayTextTitle.setAttribute('class', 'titleText') let booksDisplayTextAuthor = document.createElement('p'); booksDisplayTextAuthor.setAttribute('class', 'authorText') let booksDisplayTextPages = document.createElement('p'); booksDisplayTextPages.setAttribute('class', 'pagesText') let booksDisplayTextDisplayTitle = document.createTextNode(`${book.title}`); booksDisplayTextTitle.appendChild(booksDisplayTextDisplayTitle); let booksDisplayTextDisplayAuthor = document.createTextNode(`${book.author}`); booksDisplayTextAuthor.appendChild(booksDisplayTextDisplayAuthor) let booksDisplayTextDisplayPages = document.createTextNode(`${book.pages}`); booksDisplayTextPages.appendChild(booksDisplayTextDisplayPages); let textContainer = document.createElement('div'); textContainer.setAttribute('class', 'textContainer'); booksDisplay.appendChild(textContainer); textContainer.appendChild(booksDisplayTextTitle); textContainer.appendChild(booksDisplayTextAuthor); textContainer.appendChild(booksDisplayTextPages); booksContainer.appendChild(booksDisplay); let buttonRead = document.createElement('button') let buttonRemove = document.createElement('button'); buttonRemove.addEventListener('click', () => { booksDisplayTextTitle.textContent = 'Title:'; booksDisplayTextAuthor.textContent = 'Author:'; booksDisplayTextPages.textContent = 'Pages:'; booksDisplayImage.style.display = 'none'; imageContainer.style.border = '1px solid rgb(107, 107, 107)' }); let buttonReadText = document.createTextNode ('I have read this book'); let buttonRemoveText = document.createTextNode ('Remove a book'); buttonRead.appendChild(buttonReadText); buttonRemove.appendChild(buttonRemoveText); textContainer.appendChild(buttonRead) textContainer.appendChild(buttonRemove) }); const inputTitle = document.querySelector('#title'); const inputAuthor = document.querySelector('#author') const inputPages = document.querySelector('#pages') const inputImageUrl = document.querySelector('#imageUrl') inputImageUrl.value = ''; inputTitle.value = ''; inputAuthor.value = ''; inputPages.value = ''; const titleText = document.querySelector('.titleText'); const authorText = document.querySelector('.authorText'); const pagesText = document.querySelector('.pagesText'); const bookImageUrl = document.querySelector('.booksImage'); console.log(inputTitle) buttonConfirm.addEventListener('click', () => { bookImageUrl.src = inputImageUrl.value; titleText.textContent = 'Title:' + ' ' + inputTitle.value; authorText.textContent = 'Author:' + ' ' + inputAuthor.value; pagesText.textContent = 'Pages:' + ' ' + inputPages.value; const newBooks = books.map(newBook => { if (newBook.id == 1) { return {...newBook, author: inputAuthor.value, title: inputTitle.value, pages: inputPages.value} } return newBook; }); console.log(newBooks) }); console.log(books)
 <!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"> <link rel="stylesheet" href="./styles/style.css"> <title>Document</title> </head> <body> <div class="myLibrary"> <form class="addNewBook"> <input type="text" name="titles" id="title" placeholder="Title"> <input type="text" name="author" id="author" placeholder="Author"> <input type="number" name="pages" id="pages" placeholder="Number of pages"> <input type="link" name="imageUrl" id="imageUrl" placeholder="Image URL"> </form> <div class="buttonContainer"> <button class="buttonNewBook">Add a new book</button> <button class="confirmBook">Confirm</button> </div> <div class="booksContainer"> </div> <script src="./scripts/script.js"></script> </body> </html>

Your book is wrong formated

 let info = { id: 1, imageUrl: '', id: 2, title: 'Title:', id: 3, author: 'Author:', id: 4, pages: 'Pages:' } console.log( info )

is the same as

let info = {}
info.id = 1
info.id = 2
info.id = 3
info.id = 4
info.title = .... 

there could be only one info.id propertie

I lost time understanding the purpose of your code, but I suggest you get inspired by this way of coding...

 const newBookForm = document.forms['add-New-Book'] , books = [ { id: 1, imageUrl: '', title: 'Title-1', author: 'Author:', pages: 'Pages:' } , { id: 2, imageUrl: '', title: 'Title-2', author: 'Author:', pages: 'Pages:' } , { id: 3, imageUrl: '', title: 'Title-3', author: 'Author:', pages: 'Pages:' } , { id: 4, imageUrl: '', title: 'Title-4', author: 'Author:', pages: 'Pages:' } ] , booksContainer = document.querySelector('.booksContainer') , newBook = { id: books.reduce((r,{id})=>Math.max(r,id),0) } ; function displayNewBook(book) { let booksDisplay = document.createElement('div') booksDisplay.className = 'booksDisplay' booksDisplay.innerHTML = ` <div class="imageContainer"> <img src="${book.imageUrl}" class="booksImage" > </div> <div class="textContainer"> <p class"titleText">${book.title}</p> <p class"authorText">${book.author}</p> <p class"pagesText">${book.pages}</p> <button data-op="readed" data-ref="${book.id}"> I have read this book</button> <button data-op="remove" data-ref="${book.id}"> Remove this book</button> </div>` booksContainer.appendChild(booksDisplay) } books.forEach( displayNewBook ) ; newBookForm.onsubmit = e => e.preventDefault() // disable form submit for no page relaoding ; newBookForm.onclick = ({target: bt }) => { if (!bt.matches('button')) return; let addBook = (bt.name==='btAdd') if ( addBook && !newBookForm.checkValidity() ) { newBookForm.reportValidity() return } newBookForm.btAdd .classList.toggle('noDisplay', addBook ) newBookForm.btConfirm.classList.toggle('noDisplay', !addBook ) newBookForm.btCancel .classList.toggle('noDisplay', !addBook ) newBookForm.titles .readOnly = addBook newBookForm.author .readOnly = addBook newBookForm.pages .readOnly = addBook newBookForm.imageUrl.readOnly = addBook if (bt.name==='btConfirm') { let book = { id : ++newBook.id , imageUrl : newBookForm.imageUrl.value , title : newBookForm.titles.value , author : newBookForm.author.value , pages : newBookForm.pages.value } books.push( book ) displayNewBook( book ) newBookForm.reset() console.clear() console.log ( 'books:\n' + JSON.stringify(books).replaceAll('},{','}\n,{') ) } } booksContainer.onclick = ({target: target_Bt}) => { if (!target_Bt.matches('button[data-op]')) return // console.clear() // console.log( target_Bt.dataset.op, target_Bt.dataset.ref ) if (target_Bt.dataset.op==='readed') { // things to do with target_Bt.dataset.ref } if (target_Bt.dataset.op==='remove') { // things to do with target_Bt.dataset.ref // let idx = books.findIndex(({id})=>id=== +target_Bt.dataset.ref) target_Bt .closest('div.booksDisplay') .querySelector('div.imageContainer') .classList.add('BookRemove'); } }
 .booksContainer { font-family : Arial, Helvetica, sans-serif; font-size : 14px; } .imageContainer { width : 80px; height : 30px; background : aquamarine; } .textContainer button { margin : 0 0 2.4em 1em; } .imageContainer.BookRemove { border : 1px solid rgb(107, 107, 107); } .noDisplay { display: none; } form[name="add-New-Book"] { margin-bottom : 2em; width : 20em; } form input { margin-bottom : .4em; width : 19em; } form fieldset { padding-bottom : 0; margin-bottom : .4em; } form[name="add-New-Book"] input:read-only { background-color: lightblue; } button[name="btConfirm"] { width : 10em; background-color : #7bff00; border-radius : 4px; } button[name="btCancel"] { width : 5em; background-color : #ebb222; border-radius : 4px; } .as-console-row::after {display: none !important;} .as-console-row-code {background: yellow;}
 <form name="add-New-Book"> <fieldset> <legend> new Book </legend> <input type="text" name="titles" placeholder="Title" required> <input type="text" name="author" placeholder="Author" required> <input type="number" name="pages" placeholder="Number of pages" required min="0"> <input type="link" name="imageUrl" placeholder="Image URL" required> </fieldset> <button type="button" name="btAdd"> Add a new book </button> <button type="button" name="btConfirm" class="noDisplay"> Confirm </button> <button type="button" name="btCancel" class="noDisplay"> Cancel </button> <button type="reset">reset</button> </form> <div class="booksContainer">

Okay, I figured it out. It seems like I have to add an ID to the whole object(It was 4 before and I changed it to ID: 1. Then I added return {...newBook, author: inputAuthor.value, title: inputTitle.value, pages: inputPages.value} in a new array.

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