Build a Bookmark Manager App - Build a Bookmark Manager App(last-step)

Tell us what’s happening:

i need help here in the last step i am stuck there,

here is my code

const mainSection = document.getElementById('main-section');
const categoryDropdown = document.getElementById('category-dropdown');
const viewButton = document.getElementById('view-category-button');
const categoryList = document.getElementById('category-list');
const bookmarkSection = document.getElementById('bookmark-list-section');
const addButton = document.getElementById('add-bookmark-button');
const goBackButton = document.getElementById('close-form-button')
const formSection = document.getElementById('form-section');
const categoryHead = document.querySelector('.category-name')
const nameInput = document.getElementById('name');
const urlInput = document.getElementById('url');
const addButtonForm = document.getElementById('add-bookmark-button-form');
const insideGoBackBtn = document.getElementById('close-list-button');
const bookmarkLiSection = document.getElementById('bookmark-list-section'); 
const deleteBookmarkButton = document.getElementById('delete-bookmark-button'); 

let radioInput;
 let dropStash = ''
// first add button function
addButton.addEventListener('click', () => {
  categoryHead.textContent = categoryDropdown.value[0].toUpperCase() + categoryDropdown.value.slice(1)
  dropStash = categoryHead.textContent
  getBookmarks()
  displayOrCloseForm()
})

// go back button function
goBackButton.addEventListener('click', () => {

  displayOrCloseForm()

})
insideGoBackBtn.addEventListener('click', () => {

  displayOrHideCategory()

})
  
// getBookmarks function
const getBookmarks = () => {
  try {

  
    let storedBookmarks = localStorage.getItem('bookmarks')
    let bookmarks = storedBookmarks ?  JSON.parse(storedBookmarks) : []
  if(Array.isArray(bookmarks) && bookmarks.every(bookmark => bookmark.name && bookmark.category && bookmark.url)) {
    return bookmarks
  }else {
    return []
  }
  }catch {
    return []
  }
  
 
}

// console.log(delete localStorage['bookmarks'])

    
// add button form
addButtonForm.addEventListener('click', (e) => {
  // e.preventDefault()
  let newBookmark = {
    name: nameInput.value,
    category: categoryDropdown.value,
    url: urlInput.value,
  }
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || []
  bookmarks.push(newBookmark)
  localStorage.setItem('bookmarks', JSON.stringify(bookmarks))
  nameInput.value = ''
  urlInput.value = '' 
  displayOrCloseForm()
})

// View Button event
viewButton.addEventListener('click', (e) => {
    bookmarkLiSection.querySelector('h2').innerHTML = categoryDropdown.value[0].toUpperCase() + categoryDropdown.value.slice(1)
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks'))

  const filtered = bookmarks.filter(bookmark => bookmark.category == categoryDropdown.value)
  
    displayOrHideCategory()

  if(!Array.isArray(bookmarks) || bookmarks.length == 0) {
   
    categoryList.innerHTML = `<p>No Bookmarks Found</p>`
  }
  if(filtered.length == 0) {
        categoryList.innerHTML = `<p>No Bookmarks Found</p>`
  }else {
    categoryList.innerHTML = ''
    filtered.forEach(item => {
      let input = document.createElement('input')
      input.type = 'radio'
      input.value = item.name
      input.id = item.name
      input.name = categoryDropdown.value
      let label = document.createElement('label')
      label.htmlFor = item.name
      label.innerHTML = `<a href='${item.url}'>${item.name}</a>`;
      categoryList.append(label)
      categoryList.append(input)
      radioInput = input.value

    })
  }

})
  
// displayOrCloseForm function
const displayOrCloseForm = () => {
  mainSection.classList.toggle('hidden')
  formSection.classList.toggle('hidden')
}
// localStorage.removeItem('bookmarks') 

// displayOrHideCategory function
const displayOrHideCategory = () => {
  mainSection.classList.toggle('hidden')
  bookmarkLiSection.classList.toggle('hidden')
}

// deleteBookmarkButton event
deleteBookmarkButton.addEventListener('click', (e) => {
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks'))

  categoryList.querySelectorAll('input[type="radio"]').forEach(input => {
    if(input.checked) {
      (bookmarks.forEach(bookmark => {
        if(bookmark.name  == input.value && bookmark.category == input.name) {

        // console.log(bookmark)
        // console.log(bookmarks.contains(bookmark))
          // console.log(delete bookmarks[bookmarks.indexOf(bookmark)])
          console.log(bookmarks) 
        }
        // console.log(bookmark.name  == input.value)
        // console.log(input.value)
         
      }))
  // console.log(bookmarks.indexOf(input.checked))
     let filtered = bookmarks.filter(item => item.name == input.id)
      // console.log(bookmarks.indexOf(input.id))
      // console.log(input) 
      // console.log(filtered) 
      // console.log(input.id) 
    } 
  })
})

// console.log(localStorage.getItem('bookmarks'))   

any hint please ?

thank you :slight_smile:

Your code so far

/* file: script.js */

<!-- file: index.html -->

/* file: styles.css */

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36

Challenge Information:

Build a Bookmark Manager App - Build a Bookmark Manager App

How are you stuck?

Have you gathered any information as to what might be wrong?

It looks like you have identified the bookmark to remove: :white_check_mark:

if(bookmark.name  == input.value && bookmark.category == input.name) {

           console.log(bookmark)  //maybe change this to bookmark not bookmarks?
        }

Compare the filter above to this filter:

         
      }))

     let filtered = bookmarks.filter(item => item.name == input.id)
    } 

this filter is missing something, right?

You have the pieces you just need to put it all together.

yes i saw someone talked about it before,
it’s about category piece.

i show the white flag,
i feel it’s foggy something
if i could specify the filtered input, i donno what’s next yet
i know what to do but i donno how to do :
1 => i need to remove the specified element from the array of objects in local storage,
2 => i need to remove the radio input and it’s label from the category list

i got another problem here,
when i was clicking on view Category button event it was working fine,
but now i got an error and i can’t specify how to solve it

Uncaught TypeError: Cannot read properties of null (reading 'category')

and here is the console message

about:srcdoc:289 Uncaught TypeError: Cannot read properties of null (reading 'category')
    at about:srcdoc:289:21
    at Array.filter (<anonymous>)
    at HTMLButtonElement.<anonymous> (about:srcdoc:288:28)

Did you make changes to your code?

Then you will have to share it again.

Focus on this first.

How do you remove an element from an array?
You should write the array back to local storage when this is done.

i - i should get the index for the array that i need to remove
ii - then splice method i should use
iii - then maybe i save the changes in stash array
xi - then i set the new array after stringified it to the local storage as the new bookmark

is it good ?

1 Like

Sounds good to me. :+1:

When that is implemented you can focus on the next part. One step at a time.

const mainSection = document.getElementById('main-section');
const categoryDropdown = document.getElementById('category-dropdown');
const viewButton = document.getElementById('view-category-button');
const categoryList = document.getElementById('category-list');
const bookmarkSection = document.getElementById('bookmark-list-section');
const addButton = document.getElementById('add-bookmark-button');
const goBackButton = document.getElementById('close-form-button')
const formSection = document.getElementById('form-section');
const categoryHead = document.querySelector('.category-name')
const nameInput = document.getElementById('name');
const urlInput = document.getElementById('url');
const addButtonForm = document.getElementById('add-bookmark-button-form');
const insideGoBackBtn = document.getElementById('close-list-button');
const bookmarkLiSection = document.getElementById('bookmark-list-section'); 
const deleteBookmarkButton = document.getElementById('delete-bookmark-button'); 

let radioInput;

// first add button function
addButton.addEventListener('click', () => {
  categoryHead.textContent = categoryDropdown.value[0].toUpperCase() + categoryDropdown.value.slice(1)
  getBookmarks()
  displayOrCloseForm()
})

// go back button function
goBackButton.addEventListener('click', () => {

  displayOrCloseForm()

})
insideGoBackBtn.addEventListener('click', () => {

  displayOrHideCategory()

})
  
// getBookmarks function
const getBookmarks = () => {
  try {

  
    let storedBookmarks = localStorage.getItem('bookmarks')
    let bookmarks = storedBookmarks ?  JSON.parse(storedBookmarks) : []
  if(Array.isArray(bookmarks) && bookmarks.every(bookmark => bookmark.name && bookmark.category && bookmark.url)) {
    return bookmarks
  }else {
    return []
  }
  }catch {
    return []
  }
  

}

// console.log(delete localStorage['bookmarks'])

    
// add button form
addButtonForm.addEventListener('click', (e) => {
  // e.preventDefault()
  let newBookmark = {
    name: nameInput.value,
    category: categoryDropdown.value,
    url: urlInput.value,
  }
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || []
  bookmarks.push(newBookmark)
  localStorage.setItem('bookmarks', JSON.stringify(bookmarks))
  nameInput.value = ''
  urlInput.value = '' 
  displayOrCloseForm()
})
 
// View Button event
viewButton.addEventListener('click', (e) => {
    bookmarkSection.querySelector('h2').innerText = categoryDropdown.value[0].toUpperCase() + categoryDropdown.value.slice(1)
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks'))

  let filtered = bookmarks.filter(bookmark => bookmark.category == categoryDropdown.value)
  
    displayOrHideCategory()

  if(!Array.isArray(bookmarks) || bookmarks.length == 0) {
    
    categoryList.innerHTML = `<p>No Bookmarks Found</p>`
  }
  if(filtered.length == 0) {
        categoryList.innerHTML = `<p>No Bookmarks Found</p>`
  }else {
    categoryList.innerHTML = ''
    filtered.forEach(item => {
      let input = document.createElement('input');
      input.type = 'radio';
      input.value = item.name;
      input.id = item.name;
      input.name = categoryDropdown.value
      let label = document.createElement('label');
      label.htmlFor = item.name;
      label.innerHTML = `<a href='${item.url}'>${item.name}</a>`;
      categoryList.append(label);
      categoryList.append(input);
      radioInput = input.value;

    })
  }
 
})
  
// displayOrCloseForm function
const displayOrCloseForm = () => {
  mainSection.classList.toggle('hidden');
  formSection.classList.toggle('hidden');
}
// localStorage.removeItem('bookmarks') 

// displayOrHideCategory function
const displayOrHideCategory = () => {
  mainSection.classList.toggle('hidden')
  bookmarkLiSection.classList.toggle('hidden')
}

// deleteBookmarkButton event
deleteBookmarkButton.addEventListener('click', (e) => {
  let bookmarks = JSON.parse(localStorage.getItem('bookmarks'))
  // console.log(bookmarks)
  categoryList.querySelectorAll('input[type="radio"]').forEach(input => {
    if(input.checked) {
      (bookmarks.forEach(bookmark => {
        if(bookmark.name === input.value && bookmark.category === input.name) {
          // console.log(delete bookmarks[bookmarks.indexOf(bookmark)])

          // console.log(categoryList.querySelectorAll('input'))
// categoryList.querySelector('label').htmlFor = input.id
categoryList.querySelectorAll('label')[bookmarks.indexOf(bookmark)].remove()
          // console.log(Array(categoryList.querySelectorAll('label')))
          console.log(delete bookmarks[bookmarks.indexOf(bookmark)])
          // console.log( bookmarks[bookmarks.indexOf(bookmark)])
          // document.getElementById(input.id).remove()
          // let updated = bookmarks
          // localStorage.setItem('bookmarks', JSON.stringify(updated))
          // console.log(updated)
        }
          // console.log(categoryDropdown.value) 
        // console.log(bookmark.name  == input.value)
        // console.log(bookmark.category)
         
      }))

     let filtered = bookmarks.filter(item => item.name == input.id && item.category == categoryDropdown.value)
      // console.log(bookmarks.indexOf(input.id))
      // console.log(input) 
      // console.log(bookmarks.indexOf(filtered)) 
      // console.log(JSON.stringify(filtered)) 
      // console.log(input.id) 
    } 
  })
})

// console.log(localStorage.getItem('bookmarks'))   

Please do not post code by itself without context or comment.

Do you have a question? Did you complete it successfully?

Don’t make us guess, please?

yes i told you that i’ve a bug and i type it and you asked me to share my updated code

here you told me to share it again

Ok provide that context when you share the code then. Because we also discussed updating the delete function.

I’m also working on my own code and commenting on other forum threads.

You also did not answer this question

Did you make a change that would have caused this?

1 Like

somehow i try to manipulate to resolve the step iam stuck in,
but i can’t remember why it acts like so,
i could compare my updated code with my older one that i shared here in the top of the post to get that issue !

1 Like

Please do not post LLM-generated content to the forum.

1 Like

oO i copied the first phase code and i got the same problem result too

Please share your current code.

You still have this problem?