Module 8: (Watchlist Project) After searching can I swap div classes when the movie is found in an array?

I have been working on this problem for a couple of days… SO what I want to happen, is that when I search for a movie to add to the watchlist… if it’s a movie that I have already added, I want to:

  • find the div that is holding that objects data

  • get the first child and add a class of hidden

  • then get the second child and remove the class that’s hidden

The result should be that any movie that has already been added to the watchlist should have the “added” icon indicator displayed instead of the add to watchlist button div.

I’m not even sure if this is the correct way to go about this but here is what I have tried in index.js so far:

const formEl = document.getElementById("form-el");
const moviesHolder = document.getElementById("movies-holder");
// localStorage.clear();
let movieDescription = "";
let addIconDiv = "";

let watchlistArray = JSON.parse(localStorage.getItem("imdbMovie")) || [];

formEl.addEventListener("submit", (e) => {
  const searchFieldValue = document.getElementById("search-field").value;
  const searchNotFoundHolder = document.getElementById(
    "search-not-found-holder"
  );
  const searchNotFoundText = document.getElementById("search-not-found-text");
  const introPrompt = document.getElementById("intro-prompt");
  const mainHolder = document.getElementById("main-holder");
  movieDescription = "";
  let imdbMovieIdArray = [];
  e.preventDefault();
  fetch(
    `http://www.omdbapi.com/?apikey=my_api_key&s=${searchFieldValue}&type=movie`
  )
    .then((res) => res.json())
    .then((movieData) => {
      document.getElementById("search-field").value;
      introPrompt.classList.add("hidden");
      mainHolder.classList.remove("vertical-height");
      if (movieData.Search === undefined) {
        moviesHolder.innerHTML = "";
        searchNotFoundHolder.classList.add("search-not-fount-vertical-height");
        searchNotFoundText.classList.remove("hidden");
        searchNotFoundText.textContent =
          "Unable to find what you’re looking for. Please try another search.";
      } else {
        searchNotFoundHolder.classList.remove(
          "search-not-fount-vertical-height"
        );
        searchNotFoundHolder.classList.add("hidden");
        searchNotFoundText.classList.add("hidden");
        for (let movie of movieData.Search) {
          imdbMovieIdArray.push(movie.imdbID);
        }
      }
    })
    .then(() => {
      for (let imdbMovieId of imdbMovieIdArray) {
        fetch(
          `http://www.omdbapi.com/?apikey=my_api_key&i=${imdbMovieId}&type=movie&plot=full`
        )
          .then((res) => res.json())
          .then((imdbMovieData) => {
            // console.log(imdbMovieData);
            document.addEventListener("click", (e) => {
              if (e.target.dataset.addToWatchlist) {
                handleWatchlistItem(
                  e.target.dataset.addToWatchlist,
                  imdbMovieData
                );
              }
            });
            movieDescription += `
            <div class="movie-card-holder">
              <img src="${
                imdbMovieData.Poster === "N/A"
                  ? "/images/movie-jacket-sub.png"
                  : imdbMovieData.Poster
              }" class="movie-poster">
              <div class="movie-content-holder">
                <div class="movie-and-rating-holder">
                  <h2 class="movie-title">${imdbMovieData.Title}
                  <span class="movie-rating"><span class="star-emoji">⭐️</span>${
                    imdbMovieData.imdbRating === "N/A"
                      ? "no rating"
                      : imdbMovieData.imdbRating
                  }</span></h2>
                </div>
                <div class="time-and-genre-holder">
                  <div class="time-and-genre-container">
                    <p class="movie-time">${
                      imdbMovieData.Runtime === "N/A"
                        ? ""
                        : imdbMovieData.Runtime
                    }</p>
                    <p class="movie-genre">${
                      imdbMovieData.Genre === "N/A" ? "" : imdbMovieData.Genre
                    }</p>
                  </div>
                  <div class="add-to-watchlist-btn-holder">
                    <button class="add-to-watchlist-btn" data-add-to-watchlist=${
                      imdbMovieData.imdbID
                    }>Watchlist</button>
                    <div class="added-icon hidden">
                      Added
                    </div>
                  </div>
                </div>
                <div class="plot-holder">
                  <p>${
                    imdbMovieData.Plot === "N/A"
                      ? "<span class='no-description'>Plot not available.</span>"
                      : handlePlot(imdbMovieData)
                  }</p>
                </div>
              </div>
            </div>
            `;
            // Working here //////////////////////////////////////////////////////////////////////////////
            // if there's a match between an id in the watchlist array and an id of one of the objects
            // the search targets the movies in the watchlist array finds the add to watchlist watchlist
            // button for that movie and applies a class of hidden. Then it finds the added icon dive
            // and removes the class of hidden

            for (let watchlistItem of watchlistArray) {
              if (watchlistItem.imdbID === imdbMovieData.imdbID) {
                const addToWatchlistBtnHolder = document.querySelectorAll(
                  ".add-to-watchlist-btn-holder"
                );
                for (let addToWatchlistBtn of addToWatchlistBtnHolder) {
                  addToWatchlistBtn.children[0].classList.add("hidden");
                }
              }
            }
            // //////////////////////////////////////////////////////////////////////////////////////////
            function handleWatchlistItem(watchlistItemID, imdbMovieData) {
              const addToWatchlistBtns = document.querySelectorAll(
                ".add-to-watchlist-btn"
              );
              for (let addToWatchlistBtn of addToWatchlistBtns) {
                const watchlistBtn = addToWatchlistBtn.dataset.addToWatchlist;

                if (watchlistBtn === watchlistItemID) {
                  addToWatchlistBtn.classList.add("hidden");
                  addToWatchlistBtn.nextElementSibling.classList.remove(
                    "hidden"
                  );
                }
              }
              if (imdbMovieData.imdbID === watchlistItemID) {
                let watchlistMovie = imdbMovieData;
                watchlistArray.push(watchlistMovie);
                // console.log(watchlistArray);
                localStorage.setItem(
                  "imdbMovie",
                  JSON.stringify(watchlistArray)
                );
              }
            }
            moviesHolder.innerHTML = movieDescription;
          });
      }
    });
  formEl.reset();
});

function handlePlot(fullString) {
  document.addEventListener("click", (e) => {
    if (e.target.dataset.readMore) {
      handleReadMore(e.target.dataset.readMore, e);
    } else if (e.target.dataset.readLess) {
      handleReadLess(e.target.dataset.readLess, e);
    }
  });
  let fullPlot = fullString.Plot;
  let shortPlot =
    fullPlot.split(/\s+/).slice(0, 22).join(" ") +
    `...<button class='read-more-btn' data-read-more=${fullString.imdbID}>Read More</button>`;

  if (fullPlot > fullPlot.split(/\s+/).slice(0, 22).join(" ")) {
    return shortPlot;
  } else {
    return fullPlot;
  }
  function handleReadMore(movieID, e) {
    if (movieID === fullString.imdbID) {
      e.target.parentNode.innerHTML =
        fullPlot +
        `<button class='read-more-btn' data-read-less=${fullString.imdbID}>Read Less</button>`;
    }
  }
  function handleReadLess(movieID, e) {
    if (movieID === fullString.imdbID) {
      e.target.parentNode.innerHTML = shortPlot;
    }
  }
}

Here is my index.html:

<!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="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;800&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="index.css" />
    <script src="index.js" type="module" defer></script>
    <title>Brad Cole's Watchlist</title>
  </head>
  <body>
    <div class="site-container">
      <header>
        <h1>Find Your Film</h1>
        <a href="./watchlist.html" class="watchlist-btn">My Watchlist</a>
        <form id="form-el" class="search-form">
          <input
            type="search"
            name="search-field"
            class="search-field"
            id="search-field"
          />
          <button class="search-btn">Search</button>
        </form>
      </header>
      <main id="main-holder" class="vertical-height">
        <div id="search-not-found-holder">
          <p id="search-not-found-text"></p>
        </div>
        <div class="intro-prompt" id="intro-prompt">
          <img
            class="film-icon"
            src="./images/film-icon.svg"
            alt="icon of a clipped film strip"
          />
          <h2 class="intro-text">Start Exploring</h2>
        </div>
        <div id="movies-holder"></div>
      </main>
    </div>
  </body>
</html>

Here is my CSS:

:root {
  /* Font Colors */
  --white: #fff;
  --light-mid-grey: #a5a5a5;
  --dark-mid-grey: #9ca3af;
  --dark-grey: #787878;
  --very-dark-grey: #2e2e2f;
}

/* Josh Comeau CSS Reset */
*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
}
body {
  -webkit-font-smoothing: antialiased;
}
img,
svg {
  display: block;
  max-width: 100%;
}
input,
button {
  font: inherit;
}

/* Typography */
body {
  font-family: "Inter", sans-serif;
}
header > h1 {
  font-weight: 800;
  font-size: 2.675rem;
  color: var(--white);
}
.watchlist-btn {
  color: var(--white);
  font-weight: 700;
  font-size: 0.875rem;
}
.intro-text {
  font-size: 1.125rem;
  color: var(--very-dark-grey);
}
#search-not-found-text {
  font-size: 1.125rem;
  color: var(--dark-grey);
  font-weight: 700;
  text-align: center;
  line-height: 20px;
}
.search-btn {
  font-weight: 400;
  font-size: 0.875rem;
  color: var(--white);
  line-height: 20px;
}
input {
  font-family: "Inter", sans-serif;
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--light-mid-grey);
  letter-spacing: 0.0156em;
  line-height: 20px;
}
.movie-title {
  font-size: 1.125rem;
  font-weight: 500;
  color: var(--white);
}
.movie-rating,
.movie-time {
  color: var(--white);
  font-size: 0.75rem;
  white-space: nowrap;
}
.movie-genre {
  color: var(--white);
  font-size: 0.75rem;
}
.plot-holder > p {
  font-size: 0.875rem;
  color: var(--light-mid-grey);
  font-weight: 400;
  line-height: 20px;
}
.no-description {
  font-size: 0.75rem;
  color: #d6ffdf;
}
.watchlist-text {
  color: var(--dark-grey);
  font-size: 1.125rem;
  font-weight: 700;
}
/* Layout & Related Styling */
.vertical-height {
  height: calc(100vh - 12.5em);
}
.search-not-fount-vertical-height {
  height: calc(100vh - 14.5em);
}
html {
  height: 100%;
}
body {
  background-color: #1c1c1c;
}
header {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  object-fit: cover;
  background-image: url("/images/office-movie-posters-img.png");
  background-repeat: no-repeat;
  background-position: center;
  box-shadow: inset 0 0 0 1000px rgba(15, 10, 10, 0.7);
  height: 200px;
  text-align: center;
  max-width: 550px;
  margin: 0 auto;
  padding: 0;
}
#search-not-found-holder {
  display: flex;
  width: 321px;
  justify-content: center;
  align-items: center;
}
.film-icon {
  width: 70px;
  margin-bottom: 0.75em;
  align-self: center;
}
main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: #121212;
  max-width: 550px;
  margin: 0 auto;
  padding: 0 1.5em;
}
.intro-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-grow: 1;
}
.hidden {
  display: none;
}
#movies-holder {
  display: flex;
  max-width: 550px;
  width: 100%;
  flex-direction: column;
  margin-top: 2em;
}
.movie-card-holder {
  display: flex;
  padding-bottom: 1.537em;
  border-bottom: 1px solid #2c2c2c;
  width: 100%;
}
img {
  padding-top: 1.625em;
  display: block;
  align-self: start;
}
.movie-poster {
  width: 6.188em;
  margin-right: 1.313em;
}
.movie-content-holder {
  width: 100%;
  display: flex;
  flex-direction: column;
}
.movie-and-rating-holder {
  display: flex;
  align-items: center;
  width: 100%;
  margin-top: 2em;
}
.movie-rating {
  margin-left: 0.5em;
}
.star-emoji {
  margin-right: 0.75em;
}
.time-and-genre-holder {
  display: flex;
  margin-top: 0.75em;
  flex-direction: column;
  height: 1.75em;
}
.time-and-genre-container {
  display: flex;
  flex-direction: row;
}
.movie-time {
  margin-right: 1.125em;
}
.plot-holder {
  margin-top: 0.625em;
}
.watchlist-text {
  margin-bottom: 0.938em;
}
.added-icon {
  font-size: 0.75rem;
  color: #ffe209;
  background-image: url(./images/added-icon-hvr.svg);
  background-repeat: no-repeat;
  padding-left: 1.75em;
  background-size: contain;
  align-self: center;
}
.add-to-watchlist-btn-holder {
  display: flex;
}
/* Input, buttons, a, etc.. */
.watchlist-btn {
  background: none;
  border: none;
  cursor: pointer;
  margin-top: 1em;
  text-decoration: none;
}
.watchlist-btn:hover {
  color: #ffe209;
}
.add-to-watchlist-btn {
  background: none;
  border: none;
  color: var(--white);
  background-image: url(./images/add-to-watchlist-icon.svg);
  background-repeat: no-repeat;
  background-position: left 0 top 1px;
  background-size: 16px;
  padding-left: 1.75em;
  font-size: 0.75rem;
  cursor: pointer;
  margin-top: 1em;
}
.add-to-watchlist-btn:hover {
  color: #ffe209;
  background-image: url(./images/add-to-watchlist-icon-hvr.svg);
}
.search-form {
  position: absolute;
  bottom: -1.125em;
  display: flex;
  width: 85%;
  max-width: 462px;
}
.search-field {
  background-color: var(--very-dark-grey);
  border: none;
  padding: 0.563em 0.813em 0.563em 2.75em;
  border-radius: 6px 0 0 6px;
  width: 100%;
  background-image: url("./images/search-icon.svg");
  background-repeat: no-repeat;
  background-size: 20px;
  background-position: left 0.813em top 50%;
}
.search-btn {
  background-color: #4b4b4b;
  border: none;
  border-radius: 0 6px 6px 0;
  padding: 0.563em 0.688em 0.563em 1.063em;
  cursor: pointer;
  width: 120px;
}
input:focus {
  outline: none;
}
.read-more-btn {
  font-size: 0.75rem;
  background: none;
  border: none;
  color: var(--white);
  cursor: pointer;
}
.read-more-btn:hover {
  color: #ffe209;
}

.find-movies-btn {
  color: var(--white);
  text-decoration: none;
  margin: 0 auto;
  display: block;
  font-size: 0.875rem;
  font-weight: 700;
  background: url(./images/add-to-watchlist-icon.svg);
  background-repeat: no-repeat;
  width: 200px;
  padding-left: 25px;
}
.find-movies-btn:hover {
  color: #ffe209;
  background: url(./images/add-to-watchlist-icon-hvr.svg);
  background-repeat: no-repeat;
  padding: 0;
  width: 200px;
  padding-left: 25px;
}

@media (min-width: 700px) {
  header {
    flex-direction: row;
    justify-content: space-between;
    padding: 0 2.625em;
  }
  .time-and-genre-holder {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
  }
  .time-and-genre-container {
    margin-top: 0.063em;
  }
  .movie-genre {
    white-space: nowrap;
    margin-right: 1.75em;
  }
  .add-to-watchlist-btn {
    margin-top: 0;
  }
}
 

I also have watchlist.html:

<!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="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;800&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="index.css" />
    <title>Brad Cole's Watchlist</title>
  </head>
  <body>
    <div class="site-container">
      <header>
        <h1>My Watchlist</h1>
        <a href="./index.html" class="watchlist-btn">Search for movies</a>
      </header>
      <main id="main-holder" class="vertical-height">
        <div id="watchlist-holder"></div>
      </main>
    </div>
    <script src="watchlist.js" type="module"></script>
  </body>
</html>

and I have watchlist.js:

const watchlistText = document.getElementById("watchlist-text");
const watchlistHolder = document.getElementById("watchlist-holder");

let output = ``;
let movieItem = JSON.parse(localStorage.getItem("imdbMovie"));

if (movieItem) {
  for (let movie of movieItem) {
    output += `
    <h1>${movie.Title}</h1>
  `;
  }
  watchlistHolder.innerHTML = output;
} else {
  watchlistHolder.innerHTML = `
  <p class="watchlist-text" id="watchlist-text">Your watchlist is looking a little empty...</p>
  <a href="./index.html" class="find-movies-btn">Let's add some movies!</a>
  `;
}

I know this is a lot of code but if anyone can help out it would be an absolute God send!
Keeping my fingers crossed!

Hey @artwired, how does this current code of yours perform does it work as expected? It looks like the logic is there with your current code so wondering if you’re running into any bugs or if it just doesn’t work at all.

Everything else works as expected. Tonight I threw in an if else statement to see if the imdbID in the divs dataset and the imdbID in the watchlist array match and apparently they aren’t matching up… I have no Idea why this would be… I’ve been working on this problem ALL DAY!! :sweat_smile: It’s 2:30am here in Vancouver Canada so I gotta call it quits for the weekend… grrrrrr

@artwired, quite a complex piece of code!

Some observations: first of all, IMO, you should never post code containing an API key!
In this case, probably it does not matter , since the API is free, but it is better to always use the feature to read the required value from the environment as it is now available in Scrimba.

Re your specific problem, it seems to me that you are trying to access some DOM elements before they are actually created ( the for (let watchlistItem of watchlistArray) { is before the moviesHolder.innerHTML = movieDescription; whete you attach the newly created HTML to the DOM.

Moreover I suspect that operating on the classList of elements that you are creating dynamically in the same async function may not work as expected.

While probably it is not the best nor a “clean” solution, I remember that once I had a similar problem and solved it moving the “toggle” class logic outside the async, as an event handling for a visually “hidden” button - suppose it is referenced hiddenWatchlistBtnEl - and invoking it, inside the async, this button “click()” with a setTimeout(hiddenWatchlistBtnEl.click(), 0);.
(probably was something I found searching StackOverflow).

Finally I wonder why you are not using the data attribute to which you assigned the IMDB Id to univocally locate the associated “watchlist” button:

        const addToWatchlistBtnHolder = document.querySelectorAll(
           `[data-add-to-watchlist="${watchlistItem.imdbID}"]`);

then, using it, you can access the .parentNode and its children[1] to set the classList of the “Added” div.

I hope there is someone more experienced than me who can offer you a better solution, which can help all of us improve!

Happy debugging!

2 Likes

Good catch @giuseppeb! Edited your post for you, Brad, to redact your API key just in case.

2 Likes

@artwired , since the above observations could not be easy to understand, I made a scrim (without the “watchlist” page files) to show you the proposed “workaround”.

To run it in the Scrimba player, I had to change the API calls from “http:” to “https:”
I left (commented out) all the console.log lines I used to understand what was going on…
I also made some irrelant minor changes (a missing icon, etc.)

As said, it is far from optimal, but seems to work. If you find a better approach, let us know!

2 Likes

Thanks @roku , I’ll remember this for the future!

Hi @giuseppeb,
First of all, thank you so much for taking the time to help me with this!! I really appreciate you… I tried the code in your scrim and while I did get the right results from console.logging… the page did not reflect that when I conducted a search returning movies which included some same titles which had already been saved in my localstorage… I guess I’ll keep plugging away. Thanks Again!!

1 Like

So excited I got this working!! Thanks @giuseppeb for your help… I think a big problem was that I needed to execute the code after the dynamic HTML had been rendered. Another thing that I changed was that I looped through the watchlistArray first followed by the querySelectorAll on the add to watchlist button. Then instead of target the parent and chaining to the children I decided to keep it simple and target the button itself and the nextElementSibling. Here is my JS with the code I got to work highlighted!

const formEl = document.getElementById("form-el");
const moviesHolder = document.getElementById("movies-holder");
const watchlistCheckBtn = document.getElementById("watchlist-check-btn");
// localStorage.clear();
let movieDescription = "";
let addIconDiv = "";

let watchlistArray = JSON.parse(localStorage.getItem("imdbMovie")) || [];

formEl.addEventListener("submit", (e) => {
  const searchFieldValue = document.getElementById("search-field").value;
  const searchNotFoundHolder = document.getElementById(
    "search-not-found-holder"
  );
  const searchNotFoundText = document.getElementById("search-not-found-text");
  const introPrompt = document.getElementById("intro-prompt");
  const mainHolder = document.getElementById("main-holder");
  movieDescription = "";
  let imdbMovieIdArray = [];
  e.preventDefault();
  fetch(
    `http://www.omdbapi.com/?apikey=my_api_key&s=${searchFieldValue}&type=movie`
  )
    .then((res) => res.json())
    .then((movieData) => {
      document.getElementById("search-field").value;
      introPrompt.classList.add("hidden");
      mainHolder.classList.remove("vertical-height");
      if (movieData.Search === undefined) {
        moviesHolder.innerHTML = "";
        searchNotFoundHolder.classList.add("search-not-fount-vertical-height");
        searchNotFoundText.classList.remove("hidden");
        searchNotFoundText.textContent =
          "Unable to find what you’re looking for. Please try another search.";
      } else {
        searchNotFoundHolder.classList.remove(
          "search-not-fount-vertical-height"
        );
        searchNotFoundHolder.classList.add("hidden");
        searchNotFoundText.classList.add("hidden");
        for (let movie of movieData.Search) {
          imdbMovieIdArray.push(movie.imdbID);
        }
      }
    })
    .then(() => {
      for (let imdbMovieId of imdbMovieIdArray) {
        fetch(
          `http://www.omdbapi.com/?apikey=my_api_key&i=${imdbMovieId}&type=movie&plot=full`
        )
          .then((res) => res.json())
          .then((imdbMovieData) => {
            // console.log(imdbMovieData);
            document.addEventListener("click", (e) => {
              if (e.target.dataset.addToWatchlist) {
                handleWatchlistItem(
                  e.target.dataset.addToWatchlist,
                  imdbMovieData
                );
              }
            });
            movieDescription += `
            <div class="movie-card-holder">
              <img src="${
                imdbMovieData.Poster === "N/A"
                  ? "/images/movie-jacket-sub.png"
                  : imdbMovieData.Poster
              }" class="movie-poster">
              <div class="movie-content-holder">
                <div class="movie-and-rating-holder">
                  <h2 class="movie-title">${imdbMovieData.Title}
                  <span class="movie-rating"><span class="star-emoji">⭐️</span>${
                    imdbMovieData.imdbRating === "N/A"
                      ? "no rating"
                      : imdbMovieData.imdbRating
                  }</span></h2>
                </div>
                <div class="time-and-genre-holder">
                  <div class="time-and-genre-container">
                    <p class="movie-time">${
                      imdbMovieData.Runtime === "N/A"
                        ? ""
                        : imdbMovieData.Runtime
                    }</p>
                    <p class="movie-genre">${
                      imdbMovieData.Genre === "N/A" ? "" : imdbMovieData.Genre
                    }</p>
                  </div>
                  <div class="add-to-watchlist-btn-holder">
                    <button class="add-to-watchlist-btn" data-add-to-watchlist=${
                      imdbMovieData.imdbID
                    }>Watchlist</button>
                    <div class="added-icon hidden">
                      Added
                    </div>
                  </div>
                </div>
                <div class="plot-holder">
                  <p>${
                    imdbMovieData.Plot === "N/A"
                      ? "<span class='no-description'>Plot not available.</span>"
                      : handlePlot(imdbMovieData)
                  }</p>
                </div>
              </div>
            </div>
            `;
            function handleWatchlistItem(watchlistItemID, imdbMovieData) {
              const addToWatchlistBtns = document.querySelectorAll(
                ".add-to-watchlist-btn"
              );
              for (let addToWatchlistBtn of addToWatchlistBtns) {
                const watchlistBtn = addToWatchlistBtn.dataset.addToWatchlist;

                if (watchlistBtn === watchlistItemID) {
                  addToWatchlistBtn.classList.add("hidden");
                  addToWatchlistBtn.nextElementSibling.classList.remove(
                    "hidden"
                  );
                }
              }
              if (imdbMovieData.imdbID === watchlistItemID) {
                let watchlistMovie = imdbMovieData;
                watchlistArray.push(watchlistMovie);
                // console.log(watchlistArray);
                localStorage.setItem(
                  "imdbMovie",
                  JSON.stringify(watchlistArray)
                );
              }
            }
            moviesHolder.innerHTML = movieDescription;


            // here (below) is where I placed my solution //////////////////////////////////////////////////////////////////

            const addToWatchlistBtns = document.querySelectorAll(
              ".add-to-watchlist-btn"
            );
            for (let watchlistArrayItem of watchlistArray) {
              let watchlistObjsIDs = watchlistArrayItem.imdbID;
              for (let eachAddToWatchlistBtn of addToWatchlistBtns) {
                let addToWatchlistBtnElIDs =
                  eachAddToWatchlistBtn.dataset.addToWatchlist;
                if (addToWatchlistBtnElIDs === watchlistObjsIDs) {
                  eachAddToWatchlistBtn.classList.add("hidden");
                  eachAddToWatchlistBtn.nextElementSibling.classList.remove(
                    "hidden"
                  );
                } else {
                  console.log("no match found");
                }
              }
            }
           
          // End of solution ////////////////////////////////////////////////////////////////////////////////////////////////////////////

          });
      }
    });
  formEl.reset();
});

function handlePlot(fullString) {
  document.addEventListener("click", (e) => {
    if (e.target.dataset.readMore) {
      handleReadMore(e.target.dataset.readMore, e);
    } else if (e.target.dataset.readLess) {
      handleReadLess(e.target.dataset.readLess, e);
    }
  });
  let fullPlot = fullString.Plot;
  let shortPlot =
    fullPlot.split(/\s+/).slice(0, 22).join(" ") +
    `...<button class='read-more-btn' data-read-more=${fullString.imdbID}>Read More</button>`;

  if (fullPlot > fullPlot.split(/\s+/).slice(0, 22).join(" ")) {
    return shortPlot;
  } else {
    return fullPlot;
  }
  function handleReadMore(movieID, e) {
    if (movieID === fullString.imdbID) {
      e.target.parentNode.innerHTML =
        fullPlot +
        `<button class='read-more-btn' data-read-less=${fullString.imdbID}>Read Less</button>`;
    }
  }
  function handleReadLess(movieID, e) {
    if (movieID === fullString.imdbID) {
      e.target.parentNode.innerHTML = shortPlot;
    }
  }
}

1 Like

I really Enjoyed the course

1 Like