0

My application makes GET requests to my node/express server. To check for changes in my server code, I have added a setTimeout function. My promise function in my client side code works fine for a couple of minutes but eventually stops working and throws an error if it takes too long to get something in return from the server. Is there a way to keep the promise function running until it gets data back from the server instead of throwing an error immediately? Basically, I want the timeout to keep running in the server and check for changes and I want the getMessageData() promise function to keep running for as long as it can.

This is my factory code in my angular app that GETs data from my remote server built in nodeJS/Express:

app.factory('getMessageData', ['$q', '$http', function($q, $http) {

    var last_updated_time = 0;

    return function getData() { 
        var deferred = $q.defer();

        console.log("Time stamp is: "+last_updated_time);
        var req = $http({
            url: 'https://20161128t161542-dot-jarvis-hd-live-2.appspot-preview.com/read-message',
            method: 'GET',
            cache: false,
            params: {last_updated: last_updated_time}
        });

        req.success(function(object) {
            last_updated_time = object.time_stamp;
            deferred.resolve(object);
        });

        req.error(function(err) {
            console.log("there was an error: "+err);
            deferred.reject(err);
        });

        return deferred.promise;
    }

}]);

This is my directive code that calls and initiates the factory code to make the request:

app.directive('message', ['getMessageData', function(getMessageData) {
return {
    restrict: 'E',
    templateUrl: 'scripts/directives/message.html',
    link: function (scope) {

        function getMessage(){
            getMessageData().then(function(message_data){
                var message = message_data.data;
                scope.message = message;

                getMessage();

            }, function(err){
                console.log("Error: " + err);
            });
        }

        getMessage();

    } 
}
}]);

This is my server code for making a GET request to the /read-message url:

app.get('/read-message', function(req,res){

        var last_updated_time = req.query.last_updated;

        function checkMessage() {
            if(!last_updated_time || last_updated_time < new_time){
                updateMessage();
            }
            else {
                setTimeout(function(){
                    checkMessage();
                }, 1000 * 10); //10 seconds
            }
        }

        function updateMessage() {
            var output = {
                success: 1,
                data: message,
                time_stamp: new_time
            };

            return res.json(output);
        }

        checkMessage();


    });
Neha Sohail
  • 239
  • 3
  • 19
  • A `promise` is resolved or rejected only once (unlike an event listener) so you would need to continue to call `getMessageData` and return a new `promise` object - this post may be helpful and point you in the right direction http://stackoverflow.com/questions/15015416/how-to-set-a-global-http-timeout-in-angularjs – Foreign Object Nov 29 '16 at 00:13
  • Anyway to do long polling for this? – Neha Sohail Dec 02 '16 at 19:52

1 Answers1

-1

in the object you pass in to $http you can add a timeout property with the value you want (it's in millis). reffer to this $http

monssef
  • 1,006
  • 11
  • 12
  • Can you give more clarity please? Do I add the config object to my req? `var req = $http({ url: 'https://20161128t161542-dot-jarvis-hd-live-2.appspot-preview.com/read-message', method: 'GET', cache: false, params: {last_updated: last_updated_time} });` – Neha Sohail Nov 28 '16 at 22:42
  • just add the timeout to the end of your object. var req = $http({ url: 'https://20161128t161542-dot-jarvis-hd-live-2.appspot-previe‌​w.com/read-message', method: 'GET', cache: false, params: {last_updated: last_updated_time}, timeout: 1000}); – monssef Nov 28 '16 at 22:47
  • this doesn't work. When I add this timeout, my application waits 1 second before giving me the error. – Neha Sohail Nov 29 '16 at 05:24
  • that's what its set to, 1000ms = 1sec. change it to what fits your best. – monssef Nov 29 '16 at 11:08
  • by adding this timeout to the req function, does it run the function every 1 sec? No matter what time I put, it will fail my promise. – Neha Sohail Nov 29 '16 at 15:55
  • i think the function your looking for is setInterval(callback, timeout). the callback will be called everytime the timeout hits. it has nothing to do with $http – monssef Nov 29 '16 at 17:38
  • this doesn't solve my issue which is: Promise fails after waiting too long for data to return. The setInterval and timeout function will keep running the promise function, but it doesnt prevent the promise function from still failing. How can I prevent the promise function from failing if it has to wait for data? – Neha Sohail Dec 01 '16 at 18:07
  • the promise function doesn't fail, the request will be pending for the default amount of timeout and then the $http will reject if it got nor response, then your callback will get called with the error. so if your server takes a lot of time to respond you need to customize the timeout by the timeout you pass in to the $http. – monssef Dec 02 '16 at 21:22
  • Do I need to increase the timeout in my client to accommodate the long response time from my server? – Neha Sohail Dec 02 '16 at 21:25
  • not sure what you mean by client but $http has a default timeout, and you need to override it, set it to what fits you best $http({ url: 'https://20161128t161542-dot-jarvis-hd-live-2.appspot-preview.com/read-message', method: 'GET', cache: false, params: {last_updated: last_updated_time} timeout: 5000 // its in milliseconds }); – monssef Dec 02 '16 at 21:55