2

I send JSON POST data via a form in a MEAN environment to my server. On the server side, I process the data inside of a waterfall function, using the async library, including various operations such as: [...] - create a database entry for a new author - create a database entry for a new book - associate the new book to an author (reference to book ID) [...]

This is the method called by my route, which handles the associated POST-request:

exports.createAuthor = function(req, res) {

    console.log(req.url+' !!!POST REQUEST INCOMING!!! '+req.body);

    async.waterfall([

        function(callback){
            //create Author db entry
        },

        function(parameter, callback){
            //add author to additional directory (db action)
        },

        function(parameter, callback){
            //create book db entry
        },

        function(parameter, callback){
            //associate book to author (db action)
        }

    ], function (err, result) {
        console.log('DONE!!!');
        res.send('200');
    }); 
}

This is the client-side AngularJS controller code:

searchApp = angular.module("searchApp",[]);
searchApp.controller('authorCreator', function ($scope,$http) {

    $scope.tags = [];

    $scope.sendAuthor = function(){  

    alert('I was called!');    
    $http({
        method: 'POST',
        url: '/newauthor/',
        data: { 'authorname' : $scope.authorName,
                'authordescription' : $scope.authorDescr, 
                'bookname' : $scope.bookName, 
                'tags' : $scope.tags }
        })
        .success(function(data){
            //no actions yet
        })
        .error(function(){
            //no actions yet
        });
    };
});

This is the AngularJS form:

<div ng-controller="authorCreator">
    <form>
        <p>Author name: <input ng-model="authorName"></p>
        <p>Author description: <input ng-model="authorDescr"></p>
        <p>Book name: <input ng-model="bookName"></p>
        <p>Tags:<input ng-model="tags"></p>
        <p><button ng-click="sendAuthor()">Send</button></p>
    </form>
</div>

I noticed that, if the waterfall-process is "stuck" somewhere, meaning the client does not get an answer to it's request whatsoever, the POST request seems to be sent a second time automatically (as soon as the browser is giving a timeout according to firebug). According to firebug, a second POST request does not seem to be sent by the browser, so the call must be initiated from somewhere else. I found out by checking the database (multiple documents with identical values, except the ObjectID of course) and monitoring the node.js console window where I output incoming POST data. Again: as soon as the entire waterfall-process completes, hence the client browser does not abort the post request after a while, and res.send('200') executes, the error does not occur (= no multiple db entries). Can anyone please tell me, who does initiate this second POST request and how may I deactivate it? Cheers

Igor

Igor P.
  • 1,407
  • 2
  • 20
  • 34

3 Answers3

1

Try adding this:

exports.createAuthor = function(req, res) {
if(req.method == 'POST' && req.url = 'REQUESTEDURL'){
    console.log('POST REQUEST INCOMING!!! '+req.body);
    async.waterfall([
      //TODO...
    ]);
}

Maybe the problem is that the favicon or some other resource is doing a request to

Benjamin RD
  • 11,516
  • 14
  • 87
  • 157
  • I added this to my code. Same error. Both times the output for req.url was /newauthor/. Firebug just says "aborted" at a certain point but a second POST request does not seem to be sent. Any other ideas? – Igor P. Oct 07 '14 at 00:33
  • I added the exact same if-statement from above (without replacing REQUESTEDURL with /newauthor/). I added an additional console.log statement prior to the if-statement showing req.url. Now, no data is written to the db, still I get two POST requests by "/newauthor/". Or what else do you mean by "adding the same code"? – Igor P. Oct 07 '14 at 00:53
  • `console.log(req.url)` and check the name of the request – Benjamin RD Oct 07 '14 at 00:55
  • That's what I did. The output remains: "/newauthor/". – Igor P. Oct 07 '14 at 01:00
  • Hmmm, then, can you check if the `$scope.sendAuthor` is executed 2 times (with an `alert` or `console.log`) to verify if is the node method or if is the angular scope – Benjamin RD Oct 07 '14 at 06:05
  • I added an alert message at the beginning of the sendAuthor() method. I only get one alert, therefore it seems, that there is no second data sending on the client side. – Igor P. Oct 07 '14 at 12:58
  • What is executed 2 times, only the `async.waterfall` or the console.log message too? – Benjamin RD Oct 07 '14 at 17:14
  • The console.log message prior to the async.waterfall as well as the async.waterfall process to the point where it got stuck the first time. It seems, exports.createAuthor is being called twice. – Igor P. Oct 07 '14 at 19:39
  • http://stackoverflow.com/questions/15535336/combating-angularjs-executing-controller-twice – Benjamin RD Oct 07 '14 at 20:16
  • Thanks for that, but as I said: 1) According to Firebug, no second POST request is fired by the browser (hence no outgoing JSON data a second time). 2) I added an alert at the beginning of the AngularJS sending code and the alert message always just appears once. :( – Igor P. Oct 07 '14 at 22:28
  • Try fiddler to check if the problem is on your front-end or your backend. If appears two times in fiddler, then your problem is in the front-end http://www.telerik.com/fiddler [1] [1]:http://www.telerik.com/fiddler – Benjamin RD Oct 08 '14 at 07:38
1

After spending some time on that issue I found out, that this error seems to be based on missing answers to the client (be it via res.json, res.sendfile, ...). Therefore the client seems to re-send the request after some time, thus executing server-side code a second time. Responding to the client in reasonable time solves this issue. Sorry for the confusion.

Igor P.
  • 1,407
  • 2
  • 20
  • 34
  • Have you heard of any way to stop client from sending twice the request and be able to keep the connection stilll open ? – TOPKAT May 29 '18 at 14:22
  • 1
    Errr no. That's not what I was working with here. I am using a serversside API on a per request base. I am not using persistent connections here... – Igor P. May 31 '18 at 14:03
0

i "fixed" this by adding

 .get('/favicon.ico:1', (req, res) =>{
//do nothing because i dont care
  })
aaron
  • 68
  • 6