0

I need to send data from the front-end of my Express application, to the back-end, and then render a page using EJS which needs to display that data.

The problem is the app.post() method, and subsequently the res.render() function do not seem to execute fully or properly when I make a "manual" POST request via $.post or $.ajax

Suppose I make this POST request via JQuery

$.post("/test", {
  testData: 'Some test data.'
});

Or this POST request via AJAX

$.ajax({
  type: 'POST',
  data: {
    testData: 'Some test data here.'
  }),
  url: '/test',
 })

And I configure my app.post() method to handle that route in Express

app.post('/test', function(req, res) {
  res.render('./test.ejs', {
    testMessage: req.body.testData
  });
});

The variable testData will be sent through and received by the app.post() method. So say if I did this: console.log(req.body.testData), the output would be Some test data, so there's no problem there.

The problem is with the res.render() function, it simply doesn't work at all if the POST request is made through $.post or via AJAX$.ajax. The res.render() function does not execute or render the page through POST requests made through $.post or $.ajax.

Strangely, if did the same POST request via a form (which I do not want to do in my application because the POST request is not supposed to send data received from an input), with the EXACT same app.post() route handler in Express it works perfectly.

For example, using a form like the one below works and allows res.render() to display the page, whereas the $.post() and $.ajax methods do not. Why is that so?

<form id="form-test" role="form" action="/test" method="post">
  <input type="text" name="testData" placeholder="Test Data Goes Here" class="form-control" required>
  <button class="btn" type="submit">Submit</button>
</form>

I've found another question on StackOverflow extremely similar to mine, but with no clear workaround other than the form option (which I cannot use) : Express.js Won't Render in Post Action

Any suggestions?

Community
  • 1
  • 1
Perturbative
  • 83
  • 1
  • 2
  • 10
  • Just to clarify: You're expecting your AJAX POST request to render HTML? AJAX isn't intended to redirect the user to a different webpage the way `
    ` is...
    – RobertAKARobin Jan 14 '16 at 23:06
  • @RobertAKARobin No, the AJAX POST request is only meant to post the data to the back-end app.post() method. EJS will use the data received from the POST request in the app.post() method, and then render the HTML page. – Perturbative Jan 14 '16 at 23:12
  • @Shimal — "render" in the context of EJS just means "Take template, add data, output HTML (as a return value for the function)". It doesn't make it appear anywhere (especially in the browser viewport). – Quentin Jan 14 '16 at 23:18
  • @Quentin, I know, but there is no output HTML, when I use res.render() for either $.post or $.ajax POST requests. The HTML is only outputted if I use a HTML form, which I do not want to do. So the only time res.render() is working is when I make use of an HTML form with a POST request to send the data. – Perturbative Jan 14 '16 at 23:21
  • "but there is no output HTML" — Where are you looking for this HTML? – Quentin Jan 14 '16 at 23:22
  • @Quentin, as a displayed page. If the page is not displayed once the res.render() function has been executed, then that would mean no HTML has been outputted (correct me if I'm wrong). There is no other way that I know of to determine if the HTML was outputted or not. If I use the form, the page is displayed, if I use $.post or $.ajax requests, the page is not displayed. – Perturbative Jan 14 '16 at 23:28
  • "as a displayed page" — Which RobertAKARobin (and I) said is what you shouldn't expect. "that would mean no HTML has been outputted (correct me if I'm wrong)" — You are wrong. "is no other way that I know of to determine if the HTML was outputted or not" — Look at the Network tab of your browser's developer tools or use JavaScript to look at it (as per my answer). – Quentin Jan 14 '16 at 23:30
  • If you put `` in your page then you expect the JS to be executed. You don't expect the source code to be displayed in the browser. If you put `` then you expect the CSS to be applied to the document, not the source code to be displayed as text. If you use Ajax then the data is made available to JS, not displayed in the viewport. – Quentin Jan 14 '16 at 23:32
  • @Quentin Yes I understand that. I'm using AJAX to make the data available to Express's app.post() method, which is in another file. That's the only thing that AJAX is doing, making the data available to Express app.post() method. I never expected Ajax to output or render the data. The actual rendering of HTML is being done by EJS, in the res.render() method. That part is the part that is giving the problem when I'm using AJAX. It's not executing at all. If it did execute I would see a change in the HTML as the view that is loading (test.ejs), has a different HTML structure. – Perturbative Jan 14 '16 at 23:46
  • The 'test.ejs' view has a different HTML structure as compared to the page where the AJAX request is being sent from, so I would see the output not only in the HTML code by using Developer Tools, but visually as well. Since there is zero change in the HTML code it means that there is not HTML being outputted, as the test.ejs view's HTML hasn't been rendered and outputted by EJS – Perturbative Jan 14 '16 at 23:48
  • "The actual rendering of HTML is being done by EJS, in the res.render() method" — See my earlier comment. All that means is that you are generate a string of HTML as the return value from your render function. Because its the Express (presumably) response render function, it gets sent to the browser. The browser then *makes it available to client side JavaScript*. It **does not automatically modify the DOM**. You haven't written any code to look at the response, so you can't see anything happening. – Quentin Jan 14 '16 at 23:48
  • You've now had that explained to you in 6 different ways. So I'm going to go to bed. – Quentin Jan 14 '16 at 23:53

3 Answers3

1

The point of using Ajax is that the HTTP response is returned to JavaScript and does not replace the whole page.

If you want to load a new page, then don't use Ajax. Use a form.

If you want to handle the response in JavaScript then you need to add a handler for it.

$.post("/test", {
    testData: 'Some test data.'
}).done(function( data, textStatus, jqXHR ) {
    // Do something smarter than
    alert(data);
});
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

As others have pointed out, jQuery .post, .ajax, etc doesn't expect a redirect, it expects JSON, so that doesn't work. However, you can get the effect you're looking for with some easy JavaScript. This is how I did it when I had a similar problem:

First, I created a URL string, appending the data I wanted to pass to the server as query parameters

var urlString = 'http://hostaddress/myRoute?data1='+myData1+'data2='myData2;

Second, I did a window.location.replace like so:

window.location.replace(urlString);

Third, I made a GET route in Express to handle the incoming request:

app.get('/myRoute', function(req,res){
var myData1 = req.query.data1;
var myData2 = req.query.data2;
res.render('myView',{data1:myData1,data2:myData2});

Hope that helps.

Matt West
  • 1,376
  • 1
  • 12
  • 18
0

I faced the same problem and solved it without using $.post or $.ajax. First of all, I took button out from form element:

<form id="form-test" role="form" action="/test" method="post">
<input type="text" name="testData" placeholder="Test Data Goes Here">class="form-control" required>
</form>
<button class="btn" type="submit">Submit</button>

And I binded posting form condition to click event of button. I could also post my desired value. For example:

$(".btn").click(function(){
   if($(".form-control").val() ){
        $(".form-control").val("Desired Value");
        $("#form-test").submit();
   }else
        alert("TestData is empty");
});
purch
  • 1