How to render a page in node express from route.post?
P粉418854048
P粉418854048 2023-09-08 20:24:55
0
1
616

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.

P粉418854048
P粉418854048

reply all(1)
P粉718730956

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 the response variable and you will need to manually handle the fetched data (either manipulating the DOM insideText or redirecting to another page, e.g. using window.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 as Or simply modify the element The onclick behavior so that it has window.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.

app.get("/meme", function (req, res) {
    const memeID = req.query.id;

    // Fetch the meme details from DB or any other data sources using the specified ID
    const memeDetails = db.findById(memeID);

    res.render("pages/meme", { memeDetails });
});

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 use res.JSON() and utilize the JSON response using JS.

Meme.js

app.post("/meme", function (req, res) {
    const memeID = req.body.id;

    // Fetch the meme details from DB or any other data sources using the specified ID
    const memeDetails = db.findById(memeID);

    res.json({
        success: true,
        data: {
            id  : memeDetails.id,
            name: memeDetails.name,
            url : memeDetails.url,
        }
    })
});

meme.ejs (you can place any element that will become a meme container for the selected details)

<table>
  <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(<%= meme.id %>)">Details</button>
           </td>
        <% } %>
      </tr>
    <% }) %>
  </tbody>
</table>
<div id="selectedMeme"></div>

Then MemeDetails.js

async function handleDetailsClick(id) {
  try {
    // Make a POST request to the meme route with the meme id
    const response = await fetch("/meme", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: { id },
    });

    // Handle the response status
    if (!response.ok) {
      throw new Error("Network response was not ok");
    }
    
    // Handle the response (convert to JSON and utilize it)
    const jsonResp = await response.json();
    if (!jsonResp.success) {
      throw new Error("Something is error");
    }
    
    // put the fetched data to HTML
    const memeData = jsonResp.data;
    document.getElementById('selectedMeme').innerHTML = `
      <b>Meme name: ${memeData.name}</b>
      <br />Meme url: <a href="${memeData.url}">Click me</a>
    `;

  } catch (error) {
    // Handle any errors
    console.error(error);
    document.getElementById('selectedMeme').innerHTML = '';
  }
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template