I have a page that gets 100 memes from an api. It displays memes in a table, and each meme has a details button that takes the user to the meme's details page. I have to perform a POST request to the meme route and render the meme details page. The post request is successful, but the meme page is not rendered from render() in router.post.
Meme.js
var express = require("express"); var router = express.Router(); var bodyParser = require("body-parser"); var jsonParser = bodyParser.json(); var ensureLogIn = require("connect-ensure-login").ensureLoggedIn; var ensureLoggedIn = ensureLogIn(); router.post("/", ensureLoggedIn, jsonParser, (req, res, next) => { const meme = req.body.meme; const user = req.body.user; try { res.render("meme", { meme: meme, user: user }); } catch (error) { console.error(error); res.status(500).send("Internal Server Error"); } }); module.exports = router;
memes.egs Button:
<tbody> <% memes.forEach(meme=> { %> <tr class="meme-row <%= viewedMemeIds.includes(meme.id) ? 'viewed' : '' %>" data-meme-id="<%= meme.id %>"> <td><img src="<%= meme.url %>" alt="<%= meme.name %>"></td> <td> <%= meme.name %> </td> <% if (user) { %> <td> <button class="btn-meme details-button" onclick="handleDetailsClick(<%= JSON.stringify(meme) %>, <%= JSON.stringify(user) %>)">Details</button> </td> <% } %> </tr> <% }) %> </tbody>
MemeDetails.js:
async function handleDetailsClick(meme, user) { try { // Make a POST request to the meme route with the meme and user data const response = await fetch("/meme", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ meme, user }), }); // Handle the response status if (!response.ok) { throw new Error("Network response was not ok"); } } catch (error) { // Handle any errors console.error(error); } }
The response in the terminal is: POST /meme 200 10.677 ms - 2703, but nothing is rendered on the page.
First I would like to mention "But nothing is rendered on the page".
It never automatically renders the page, as it is stated in MDN Webdocs that
fetch()
is used to fetch resources from the network using AJAX calls. The resource you get will be stored in theresponse
variable and you will need to manually handle the fetched data (either manipulating the DOM insideText or redirecting to another page, e.g. usingwindow.href.location)
However, POST requests are typically used to create/modify data on the server (please read HTTP Methods). I see you are using POST request to render the page/navigate to another page. GET is the HTTP method used to request data from the server.
I think you'd better change the way you handle
handleDetailsClick
. Instead of passing the entire meme data, you can use HTML elements such asOr simply modify the
element The
onclick
behavior so that it haswindow.location.href=".../meme?id= "
Then, on the Express side, you can modify the POST route to GET and get the specific ID in the query string so you can search for it from a database etc. and render the page using
res.render()
Just like the example below.Hope it helps you
updated
As you mentioned the distribution requirements, you can slightly modify the POST routing code above (you can use just the ID or the whole data, depending on the distribution requirements) instead of using
res.render()
To render an html page, you simply useres.JSON()
and utilize the JSON response using JS.Meme.js
meme.ejs (you can place any element that will become a meme container for the selected details)
Then MemeDetails.js