Search code examples
javascriptmongodbexpressejs

Displaying a message on screen after being redirected to index


I have a main index page which displays 18 divs, each div representing a book. When you click on the div, you can find out various things about the book. The title, author, summary, etc. There's also a button that says "Add to Library" where you can add the book to a Collections array. There's also a user profile page that sorts the Collections array by most recent so you can see which books any user has added to their library.

GET for book page.

router.get("/book/:title", async function (req, res, next) {
  const bookId = parseInt(req.params.title);
  const book = data.PopularBooks.find((book) => book.id === bookId);
  res.render("book", { book });
});

POST for book page.

router.post("/book/:title", async (req, res, next) => {
  try {
    const user = await User.findById(req.user.id);
    if (!user) {
      return res.status(404).send("User not found");
    }

    const existingBook = user.book.find(
      (book) => book.title === req.body.title
    );
    if (existingBook) {
      return res.redirect("/");
    }

    const newBook = {
      title: req.body.title,
      image: req.body.image,
    };

    user.book.push(newBook);

    await user.save();

    res.redirect("/");
  } catch (error) {
    res.status(500).send("Error adding book");
  }
});

I also have a div in my index page that shows the message, which is set to hide by default.

<div id="message">Book already added to library</div>

When I already have the book added to my Collections and try adding it again, I'm automatically redirected to the index page. What I've been trying to figure out is how I can change the display from hide to block (or whatever) only after I fail at adding the book to the Collections array twice. That way when the user is redirected, they understand it's because the book has already been added to the array instead of assuming it's some type of error.


Solution

  • You can't pass a data object in the res.redirect method to your views so you have think linear for this one. In your router.post("/book/:title"...) function just pass a query parameter such as the book title like so:

    if (existingBook) {
      return res.redirect(`/?duplicate=${existingBook.title}`);
    }
    

    Then update your router.get("/"...) to always check for the the existence of a query parameter that matches the name duplicate like so:

    app.get('/', async (req, res, next) => {
       const duplicate = req.query.duplicate ?? false; // Nullish coalescing operator (??)
       
       if(duplicate !== false){ // duplicate has a value
        res.render("index", { duplicate });
       } else{
          // Do all of your normal code
          //...
       }
    }); 
    

    In your index page you can just use ejs to check for the duplicate object and display your message like so:

    <% if (duplicate) { %>
       <div id="message">The Book <%= duplicate %> was already added to your library</div>
    <% } %>