Search code examples
node.jsajaxexpresspostfeathersjs

Is it possible to POST from the same URL without refreshing the page?


I'm using ajax to do so and am responding with res.end on the backend but so far, I can only POST once. Here is my code:

Server

app.post("/awesome", passwordless.restricted({ failureRedirect: "/" }), (req, res, next) => {
  // ...do a bunch of stuff
  res.end();
});

Client

$("[data-new-save]").on("click", function () {
  $.ajax({
    url: "/awesome",
    type: "POST",
    data: awesomeDetails,
    success: function () {
      console.log("Cool beans");
      refreshContent(); // Re-renders content

      // Feedback
      $("nav").after("<div class=\"flash success\">Success!</div>");

      setTimeout(function () {
        $(".flash").remove();
      }, 5000);
    },
    error: function () {
      console.log("Welp");

      // Feedback
      $(".navigation").after("<div class=\"flash error\">Failure</div>");

      setTimeout(function () {
        $(".flash").remove();
      }, 5000);
    }
  });
});

Solution

  • This sounds like a case for event-delegation. The best guess I have is that your refreshContent() function is removing the original [data-new-save] elements and creating new ones. This will cause the bound click event to be removed as well as it is a property of the DOM nodes that existed when it was originally called. You can get around this by delegating the event to a DOM node that does not get "refreshed", I'm assuming that the <body> tag does not get redrawn, only some set of children, so if you target <body> and look for selectors that match "[data-new-save]" it should function properly:

    $('body').on('click', "[data-new-save]", function () {
       $.ajax({
        url: "/awesome",
        type: "POST",
        data: awesomeDetails,
        success: function () {
          console.log("Cool beans");
          refreshContent(); // Re-renders content
    
          // Feedback
          $("nav").after("<div class=\"flash success\">Success!</div>");
    
          setTimeout(function () {
            $(".flash").remove();
          }, 5000);
        },
        error: function () {
          console.log("Welp");
    
          // Feedback
          $(".navigation").after("<div class=\"flash error\">Failure</div>");
    
          setTimeout(function () {
            $(".flash").remove();
          }, 5000);
        }
      });
    });