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

Time:07-18

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 >
    
  <form >
    <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 >
    <button >Add a new book</button>
    <button >Confirm</button>
  </div>

  <div >
   
  </div>
    

    
    <script src="./scripts/script.js"></script>
</body>
</html>

CodePudding user response:

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 >
    <img src="${book.imageUrl}"  >
  </div>
  <div >
    <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" > Confirm </button>
  <button type="button" name="btCancel"  > Cancel </button>
  <button type="reset">reset</button>
</form>

<div >

CodePudding user response:

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.

  • Related