Build a Bookmark Manager App - Build a Bookmark Manager App

Tell us what’s happening:

Hello guys. I have written this code that seems to function as expected, but doesn’t fulfill the tests bellow. Please help me by pointing out what should I fix exactly in order to make it work?
tests: 5-11-17-18-19-20-22-23

Your code so far


const elements={
    // elements of the first section
    mainSelection:document.getElementById ("main-section"),
    selectedChoice :document.getElementById("category-dropdown"),
    viewCatBtn: document.getElementById("view-category-button"),
    addBookmarkBtn: document.getElementById("add-bookmark-button"),
 // second section elements that receives the bookmark data
    formSelection: document.getElementById("form-section"),
    nameInput: document.getElementById("name"),
    urlInput: document.getElementById("url"),
    closeFormBtn: document.getElementById("close-form-button"),
    addBookmarkBtn2: document.getElementById("add-bookmark-button-form"),
    // third section elements that presents the list of bookmarks
    listSection: document.getElementById("bookmark-list-section"),
    categoryList: document.getElementById("category-list"),
    closeListBtn: document.getElementById("close-list-button"),
    deleteBookmarkBtn: document.getElementById("delete-bookmark-button"),
    categoryName: document.querySelector(".category-name"),
}
const bookmarks =[];

// const getBookmarks()=>{

// }
const displayOrCloseForm=()=>{
    elements.mainSelection.classList.toggle("hidden");
    elements.formSelection.classList.toggle("hidden");
}
elements.addBookmarkBtn.addEventListener("click",()=>{
    displayOrCloseForm();
    elements.categoryName.innerText= elements.selectedChoice.value;
});
elements.closeFormBtn.addEventListener("click",()=>{
    displayOrCloseForm();
});
const displayOrHideCategory=()=>{
    elements.mainSelection.classList.toggle("hidden");
    elements.listSection.classList.toggle("hidden");
}
elements.closeListBtn.addEventListener("click",()=>{
    displayOrHideCategory()
})
const clearEntries=()=>{
     elements.nameInput.value="";
    elements.urlInput.value="";
}
const getBookmarks =()=>{
    const Selected=elements.selectedChoice.value;
    const storedBookmarks= JSON.parse(localStorage.getItem("bookmarks"));
    elements.categoryName.innerText= Selected;
    // console.log(storedBookmarks.filter((item)=>item.category===Selected))
    // return storedBookmarks.filter((item)=>item.category===Selected);
    if(Array.isArray(storedBookmarks)){
        return storedBookmarks;
    }
    return [];
   }

const getFilteredBookMarks=()=>{
    Selected= elements.selectedChoice.value;
    const storedBookmarks= JSON.parse(localStorage.getItem("bookmarks"));
    let result=[]
    if(Array.isArray(storedBookmarks)){
    for(const bookMark of storedBookmarks){
        if(bookMark.category === Selected){
            result.unshift(bookMark);
         }
    }
    }
    return result;
}
const updateBookmarkList=()=>{
    let result = getFilteredBookMarks();
    elements.categoryList.innerHTML="";
    if(result.length>0){
        result.forEach((item)=>{
        let htmlCode =`<h3>${item.name}</h3>
        <br>
        <label for="${item.id}">
        <a href="${item.url}" target="_blank">${item.name}</a>
        </label>
        <input id="${item.id}" value="${item.name}"type="radio" name="books" >
       `
        elements.categoryList.innerHTML+= htmlCode;
    }) 
    }else{
        elements.categoryList.innerHTML = "<p>No Bookmarks Found</p>";
    }
}
elements.viewCatBtn.addEventListener("click",()=>{
    
    displayOrHideCategory()
    elements.categoryName.innerText= elements.selectedChoice.value;
    updateBookmarkList();
})

const valuesAreClean=(name,url)=>{
    return name!=="" && url!==""? true:false;
}
const elementIsNew=(name,url)=>{
    let data= getBookmarks();
    for(const item of data){
        if(item.name=== name&&url===item.url){
            console.log(`${item.name} === ${name}`)
            console.log(`${item.url} === ${url}`)
            return false;
        }
    }return true;

    // return data.some((item)=>{item.name=== name&&url===item.url}) // always returns false
}
const pushToArray=()=>{
    const category= elements.selectedChoice.value;
        const name= elements.nameInput.value;
        const url= elements.urlInput.value;
    if(valuesAreClean(name,url) && elementIsNew(name,url)){
        
    const obj={
        id: `${category}-${Date.now()}`,
        name:name,
        url:url,
    category:category}
    bookmarks.push(obj);
    clearEntries();
    submitToLocalStorage();
    }else if(!valuesAreClean(name,url)){
        
    alert("Please fill in both fields");
        return;
    }else if(!elementIsNew(name,url)){
        alert("element already exists!");
        return;
    }
   
}
const submitToLocalStorage=()=>{
    localStorage.setItem("bookmarks",JSON.stringify(bookmarks));
}
elements.addBookmarkBtn2.addEventListener("click",()=>{
    displayOrCloseForm();
    pushToArray();
});
const deleteBookMark=()=>{
    let inputs= document.getElementsByName("books")
    let index;
    inputs.forEach((input)=>{
        if(input.checked){
            index= bookmarks.findIndex((value)=>value= input.value);
        }
    })
    bookmarks.splice(index,1);
    submitToLocalStorage();
    updateBookmarkList()
}
elements.deleteBookmarkBtn.addEventListener("click",deleteBookMark);


// 5. When the bookmarks key in the localStorage does not contain a valid array of bookmark objects, the getBookmarks function should return an empty array.
// 11. When you click #add-bookmark-button-form, you should update the bookmarks key stored in the local storage by adding an object to the end of the array. The added object should have name set to the value of the #name input, category set to the value of the selected option from the category dropdown, and url set to the value of the #url input.
// 17. When you click #view-category-button, you should add a p element with the text No Bookmarks Found to #category-list's inner HTML if none of the bookmarks in local storage have the selected category.
// 18. When you click the #view-category-button, you should modify the #category-list element's inner HTML by adding a radio button. The radio button should have the id and value attributes set to the bookmark name for each bookmark in the selected category. Additionally, each radio button should have the same name attribute.
// 19. Each radio button added to #category-list's inner HTML should have a corresponding label containing an anchor element with the bookmark name and the href attribute set to the bookmark URL.
// 20. Each label element should contain an anchor element with the bookmark name as text, and the href attribute set to the bookmark URL.
// 22. When you click the #close-list-button and then open any category, the #category-list should contain only data relevant for the selected category, without duplicating entries.
// 23. When you click the #delete-bookmark-button, you should delete the bookmark corresponding to the selected radio button and appropriate category from the local storage and update the displayed bookmark list.

Your browser information:

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

Challenge Information:

Build a Bookmark Manager App - Build a Bookmark Manager App

Hi @zakariaestics

Please update your post to include the code.

Happy coding

My bad, I adjusted the code.

is there any response please!

Hi @zakariaestics

When I add a bookmark, I don’t see it in View Categories.

Happy coding

I can’t know with the freecodecamp console because the program works fine in my vs and fcc console doesn’t show the exact line where the problem happened.

do you mean you are getting an error? what error is that?

Uncaught ReferenceError: Selected is not defined

I fixed it by defining a variable.
Now the list appears, but I still need help to make tests.


const elements={
    // elements of the first section
    mainSelection:document.getElementById ("main-section"),
    selectedChoice :document.getElementById("category-dropdown"),
    viewCatBtn: document.getElementById("view-category-button"),
    addBookmarkBtn: document.getElementById("add-bookmark-button"),
 // second section elements that receives the bookmark data
    formSelection: document.getElementById("form-section"),
    nameInput: document.getElementById("name"),
    urlInput: document.getElementById("url"),
    closeFormBtn: document.getElementById("close-form-button"),
    addBookmarkBtn2: document.getElementById("add-bookmark-button-form"),
    // third section elements that presents the list of bookmarks
    listSection: document.getElementById("bookmark-list-section"),
    categoryList: document.getElementById("category-list"),
    closeListBtn: document.getElementById("close-list-button"),
    deleteBookmarkBtn: document.getElementById("delete-bookmark-button"),
    categoryName: document.querySelector(".category-name"),
}
const bookmarks =[];

// const getBookmarks()=>{

// }
const displayOrCloseForm=()=>{
    elements.mainSelection.classList.toggle("hidden");
    elements.formSelection.classList.toggle("hidden");
}
elements.addBookmarkBtn.addEventListener("click",()=>{
    displayOrCloseForm();
    elements.categoryName.innerText= elements.selectedChoice.value;
});
elements.closeFormBtn.addEventListener("click",()=>{
    displayOrCloseForm();
});
const displayOrHideCategory=()=>{
    elements.mainSelection.classList.toggle("hidden");
    elements.listSection.classList.toggle("hidden");
}
elements.closeListBtn.addEventListener("click",()=>{
    displayOrHideCategory()
})
const clearEntries=()=>{
     elements.nameInput.value="";
    elements.urlInput.value="";
}
const getBookmarks =()=>{
    const Selected=elements.selectedChoice.value;
    const storedBookmarks= JSON.parse(localStorage.getItem("bookmarks"));
    elements.categoryName.innerText= Selected;
    // console.log(storedBookmarks.filter((item)=>item.category===Selected))
    // return storedBookmarks.filter((item)=>item.category===Selected);
    if(Array.isArray(storedBookmarks)){
        return storedBookmarks;
    }
    return [];
   }

const getFilteredBookMarks=()=>{
    const Selected= elements.selectedChoice.value;
    const storedBookmarks= JSON.parse(localStorage.getItem("bookmarks"));
    let result=[]
    if(Array.isArray(storedBookmarks)){
    for(const bookMark of storedBookmarks){
        if(bookMark.category === Selected){
            result.unshift(bookMark);
         }
    }
    }
    return result;
}
const updateBookmarkList=()=>{
    let result = getFilteredBookMarks();
    elements.categoryList.innerHTML="";
    if(result.length>0){
        result.forEach((item)=>{
        let htmlCode =`<h3>${item.name}</h3>
        <br>
        <label for="${item.id}">
        <a href="${item.url}" target="_blank">${item.name}</a>
        </label>
        <input id="${item.id}" value="${item.name}"type="radio" name="books" >
       `
        elements.categoryList.innerHTML+= htmlCode;
    }) 
    }else{
        elements.categoryList.innerHTML = "<p>No Bookmarks Found</p>";
    }
}
elements.viewCatBtn.addEventListener("click",()=>{
    
    displayOrHideCategory()
    elements.categoryName.innerText= elements.selectedChoice.value;
    updateBookmarkList();
})

const valuesAreClean=(name,url)=>{
    return name!=="" && url!==""? true:false;
}
const elementIsNew=(name,url)=>{
    let data= getBookmarks();
    for(const item of data){
        if(item.name=== name&&url===item.url){
            console.log(`${item.name} === ${name}`)
            console.log(`${item.url} === ${url}`)
            return false;
        }
    }return true;

    // return data.some((item)=>{item.name=== name&&url===item.url}) // always returns false
}
const pushToArray=()=>{
    const category= elements.selectedChoice.value;
        const name= elements.nameInput.value;
        const url= elements.urlInput.value;
    if(valuesAreClean(name,url) && elementIsNew(name,url)){
        
    const obj={
        id: `${category}-${Date.now()}`,
        name:name,
        url:url,
    category:category}
    bookmarks.push(obj);
    clearEntries();
    submitToLocalStorage();
    }else if(!valuesAreClean(name,url)){
        
    alert("Please fill in both fields");
        return;
    }else if(!elementIsNew(name,url)){
        alert("element already exists!");
        return;
    }
   
}
const submitToLocalStorage=()=>{
    localStorage.setItem("bookmarks",JSON.stringify(bookmarks));
}
elements.addBookmarkBtn2.addEventListener("click",()=>{
    displayOrCloseForm();
    pushToArray();
});
const deleteBookMark=()=>{
    let inputs= document.getElementsByName("books")
    let index;
    inputs.forEach((input)=>{
        if(input.checked){
            index= bookmarks.findIndex((value)=>value= input.value);
        }
    })
    bookmarks.splice(index,1);
    submitToLocalStorage();
    updateBookmarkList()
}
elements.deleteBookmarkBtn.addEventListener("click",deleteBookMark);


// 5. When the bookmarks key in the localStorage does not contain a valid array of bookmark objects, the getBookmarks function should return an empty array.
// 11. When you click #add-bookmark-button-form, you should update the bookmarks key stored in the local storage by adding an object to the end of the array. The added object should have name set to the value of the #name input, category set to the value of the selected option from the category dropdown, and url set to the value of the #url input.
// 17. When you click #view-category-button, you should add a p element with the text No Bookmarks Found to #category-list's inner HTML if none of the bookmarks in local storage have the selected category.
// 18. When you click the #view-category-button, you should modify the #category-list element's inner HTML by adding a radio button. The radio button should have the id and value attributes set to the bookmark name for each bookmark in the selected category. Additionally, each radio button should have the same name attribute.
// 19. Each radio button added to #category-list's inner HTML should have a corresponding label containing an anchor element with the bookmark name and the href attribute set to the bookmark URL.
// 20. Each label element should contain an anchor element with the bookmark name as text, and the href attribute set to the bookmark URL.
// 22. When you click the #close-list-button and then open any category, the #category-list should contain only data relevant for the selected category, without duplicating entries.
// 23. When you click the #delete-bookmark-button, you should delete the bookmark corresponding to the selected radio button and appropriate category from the local storage and update the displayed bookmark list.

Hi @zakariaestics

When I select View Category then Delete Bookmarkwithout selecting a bookmark, the bookmark is deleted. This should happen after a bookmark is selected.

Happy coding

Thank you for pointing that out!
The problem is fixed.

const deleteBookMark=()=>{
    let inputs= document.getElementsByName("books")
    let index;
    inputs.forEach((input)=>{
        if(input.checked){
            index= bookmarks.findIndex((value)=>value= input.value);
        }
    })
    if(!isNaN(index)){
        bookmarks.splice(index,1);
    }
    submitToLocalStorage();
    updateBookmarkList()
}

Please, if anyone has already succeeded in making this project help me see what it demands.