Build a Bookmark Manager App - Build a Bookmark Manager App

Tell us what’s happening:

Having trouble with this one:

  1. When you click #add-bookmark-button, you should update the inner text of .category-name to be the value of the selected option from #category-dropdown.

Isn’t that what i’m doing:

addBookmarkButton.addEventListener("click", () => {
  categoryName.innerText = categoryDropdown.value;
  displayOrCloseForm();
});

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/141.0.0.0 Safari/537.36 Edg/141.0.0.0

Challenge Information:

Build a Bookmark Manager App - Build a Bookmark Manager App

const mainSection = document.getElementById("main-section");
const formSection = document.getElementById("form-section");
const addBookmarkButton = document.getElementById("add-bookmark-button");
const categoryDropdown = document.getElementById("category-dropdown");
const categoryName = document.getElementsByClassName("category-name");
const closeFormButton = document.getElementById("close-form-button");
const addBookmarkButtonForm = document.getElementById("add-bookmark-button-form");
const nameInput = document.getElementById("name");
const urlInput = document.getElementById("url");



function getBookmarks() {
  
  const retrievedSettings = JSON.parse(localStorage.getItem("bookmarks")) || [];
  return retrievedSettings
}




console.log(getBookmarks())

function displayOrCloseForm() {
  mainSection.classList.toggle('hidden');
  formSection.classList.toggle('hidden');
}

addBookmarkButton.addEventListener("click", () => {
  categoryName.innerText = categoryDropdown.value;
  displayOrCloseForm();
});

console.log(categoryDropdown.value)
console.log(categoryName.innerText)

closeFormButton.addEventListener("click", () => {
  displayOrCloseForm();
});

addBookmarkButtonForm.addEventListener("click", () => {
  const bookmarkObj = {
    name: nameInput.value,
    category: categoryDropdown.value,
    url: urlInput.value,
  };

  localStorage.setItem('bookmarks', JSON.stringify(bookmarkObj));
  nameInput.value = "";
  urlInput.value = "";
  displayOrCloseForm();
});

function displayOrHideCategory() {
  displayOrCloseForm();
}


share your html too please

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=0.0">
    <title>Bookmark Manager</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <main>
        <section id="main-section">
            <h1>Bookmark Manager</h1>
            <div id="dropdown">
                <label for="category-dropdown">Select a category:</label>
                <select id="category-dropdown" name="options">
                    <option value="news" selected>News</option>
                    <option value="entertainment">Entertainment</option>
                    <option value="work">Work</option>
                    <option value="miscellaneous">Miscellaneous</option>
                </select>
            </div>
            <div id="buttons">
                <button type="button" id="view-category-button">View Category</button>
                <button type="button" id="add-bookmark-button">Add Bookmark</button>
            </div>
        </section>

        <section id="form-section" class="hidden">
            <form>
                <h2 class="category-name"></h2>
                <div>
                    <label for="name">Name:</label>
                    <input type="text" id="name">
                </div>
                <div>
                    <label for="url">URL:</label>
                    <input type="text" id="url">
                </div>
                <div>
                    <button type="button" id="close-form-button">Go Back</button>
                    <button type="button" id="add-bookmark-button-form">Add Bookmark</button>
                </div>
            </form>
        </section>

        <section id="bookmark-list-section" class="hidden">
            <h2 class="category-name"></h2>
            <div id="category-list">
            </div>
            <div>
                <button type="button" id="close-list-button">Go Back</button>
                <button type="button" id="delete-bookmark-button">Delete Bookmark</button>
            </div>
        </section>

    </main>
    <script src="script.js"></script>
</body>

</html>
:root {
  --light-grey: #f5f6f7;
  --dark-grey: #0a0a23;
  --yellow: #f1be32;
  --golden-yellow: #feac32;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: flex;
  justify-content: center;
}

body {
  background-color: var(--dark-grey);
}

.hidden {
  display: none;
}

section {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

select,
input,
label {
  margin-left: 10px;
}

div {
  padding: 30px;
  display: flex;
  justify-content: center;
}

.close-form-button {
  background: none;
  border: none;
  cursor: pointer;
}

h1, h2 {
  margin-top: 20px;
  text-align: center;
}

#category-list {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  background-color: var(--light-grey);
  align-self: center;
  width: 80%;
  margin-top: 15px;
  border-radius: 10px;
}

#category-list,
h1,
h2,
label {
  color: var(--light-grey);
}

#category-list p {
  color: var(--dark-grey);
}

button {
  cursor: pointer;
  padding: 5px;
  width: 100px;
  margin: 10px;
  color: var(--dark-grey);
  background-color: var(--golden-yellow);
  background-image: linear-gradient(#fecc4c, #ffac33);
  border-color: var(--golden-yellow);
  border-width: 3px;
}

button:hover {
  background-image: linear-gradient(#ffcc4c, #f89808);
}

section {
  margin-top: 60px;
  border: 2px solid var(--golden-yellow);
  width: fit-content;
  border-radius: 10px;
}

here you may want to add a console.log of localStorage.getItem("bookmarks"), there are more invalid values then the item not existing in local storage

function getBookmarks() {
  
  let retrievedSettings = JSON.parse(localStorage.getItem("bookmarks")) || [];

  let requiredKeys = ["name", "category", "url"];
  let allHaveKeys = retrievedSettings.every(obj =>
  requiredKeys.every(key => key in obj)
);
  console.log(allHaveKeys)

  if (!allHaveKeys) {
    retrievedSettings = [];
  }
  
  return retrievedSettings
}

console.log(localStorage.getItem("bookmarks"))

the console.log shows this:

[{"name":"Troy Metreson","category":"news","url":"test example3.com"},{"name":"","category":"news","url":""},{"name":"","category":"news","url":""},{"name":"","category":"news","url":""},{"name":"","category":"entertainment","url":""},{"name":"Nina Metreson","category":"entertainment","url":"nina@metreson.com"},{"name":"Nina Metreson","category":"entertainment","url":"nina@metreson.com"}]

Isn’t that what it’s supposed to show?

are you checking what appear there when you run the tests using the browser console? the tests add values to the local storage to test, the only way to see is using the browser console

also you need to look before using JSON.parse, there are specific invalid values that would make that error out

I’ve put the console.log at the top of the function, then called the function afterwards.

function getBookmarks() {

  console.log(localStorage.getItem("bookmarks"))
  
  let retrievedSettings = JSON.parse(localStorage.getItem("bookmarks")) || [];

  let requiredKeys = ["name", "category", "url"];
  let allHaveKeys = retrievedSettings.every(obj =>
  requiredKeys.every(key => key in obj)
);
  console.log(allHaveKeys)

  if (!allHaveKeys) {
    retrievedSettings = [];
  }
  
  return retrievedSettings
}

console.log(getBookmarks())

i’ve opened up the browser console:

[{"name":"Troy Metreson","category":"news","url":"test example3.com"},{"name":"","category":"news","url":""},{"name":"","category":"news","url":""},{"name":"","category":"news","url":""},{"name":"","category":"entertainment","url":""},{"name":"Nina Metreson","category":"entertainment","url":"nina@metreson.com"},{"name":"Nina Metreson","category":"entertainment","url":"nina@metreson.com"}]
frame.ts:318 true
frame.ts:318 

is it showing anything different to the FCC console?

when you run the tests you should see all the things that are saved in localStorage to test

make sure to not have messages in the console hidden, there are settings that hide some types of messages

I believe this is the right screen?

i havent really used this very much - what am i meant to be looking at exactly?

that is not the console, that looks like a different tab

image

there is a tab named console, keep that open when you run the tests, if you have a console.log in the right place it will show you all the things that are saved in local storage for the tests

1 Like
function getBookmarks() {

  console.log(retrievedSettings)
  
  let retrievedSettings = JSON.parse(localStorage.getItem("bookmarks")) || [];
  
  console.log(retrievedSettings)

  let requiredKeys = ["name", "category", "url"];
  let allHaveKeys = retrievedSettings.every(obj =>
  requiredKeys.every(key => key in obj)
);
  console.log(allHaveKeys)

  if (!allHaveKeys) {
    retrievedSettings = [];
  }

  
  console.log(retrievedSettings)
  return retrievedSettings
}

I’m not sure what the right place is, but i have put one before the parse, after the parse and one just before the return statement - i’m guessing one of those is the right place?

Here is the console:

what am i meant to be looking at in the console?

this would not allow you to log the value of retrievedSettings, you can’t log a variable before it is declared

you should log localStorage.getItem("bookmarks")

like console.log({localStorageContent: localStorage.getItem("bookmarks"})