Angular making pseudo-synchronous HTTP requests

Tags: ,



I want to construct a mechanism that would access a database via POST requests. So far, I do received the desired data, but am have issues with the timing. Here are three pieces of code that I’m using (simplified to keep the focus of the question).

First, a factory handling the HTTP request vis-à-vis a servlet:

var My_Web = angular.module('My_Web'); 

My_Web.factory('DB_Services', function($http , $q) {
    var l_Result ;
    var DB_Services = function(p_Query) {
                            var deferred = $q.defer();
                            var url     = "http://localhost:8080/demo/servlets/servlet/Test_ui?";
                            var params  = "data=" + p_Query ;
                            var Sending = url + params ;

                            $http.post(Sending).
                                        success(function(data, status, headers, config) {
                                             deferred.resolve(data);
                                        }).
                                        error(function(data, status, headers, config) {
                                             deferred.reject(status);
                                        });
                                         return deferred.promise;
        
                        }
                      
    return DB_Services;
    });

Second, a general purpose function handling the promise (or so I meant) exposed to all the controllers that would need to extract data from the remote DB:

$rootScope.Get_Data_from_DB = function(p_Query) {
    DB_Services(p_Query).then(function(d) {
        console.log("In Get_Data_from_DB; Received data is: " + JSON.stringify(d));
        $scope.data = d;
    });
};                    

Third, one example within one of the controllers:

$scope.Search_Lookups = function () {
    
    console.log ("search for lookup data...") ;
    
    var l_Lookup_Type = document.getElementById("THISONE").value ;

    var l_Send_Request_Data = '{"Requestor_ID":"4321" , "Request_Details" : { "Data_type" : "' + l_Lookup_Type + '" } }' ;
    
    console.log("Sending Request: " + l_Send_Request_Data) ;
    
    l_Data = $rootScope.Get_Data_from_DB(p_Query) ;
    
    console.log ("Received response: " + l_Data) ;

    Deploy_data(l_Data) ;
    
}

The function Deploy_data(l_Data) is responsible of dismembering the received data and put the relevant pieces on screen.

What happens is that I get on the console the string Received response: undefined and immediately after the result of the retrieval as In Get_Data_from_DB; Received data is: (here I get the data).

The Received response: undefined is printed from the invoking function (third piece of code), whereas the output with the actual data is received and printed from within the second piece of code above. This means that the invocation to Deploy_data would not receive the extracted data.

Once again, the same mechanism (i.e. the factory $rootScope.Get_Data_from_DB) would be vastly used by many controllers.

I thought of using $scope.$watch but I’m not sure because the same user might be triggering several queries at the same time (e.g. request a report that might take few seconds to arrive and, in the meantime, ask for something else).

Answer

I think I found a solution (at least it appears to be ok for the time being). The global function Get_Data_from_DB accepts a second parameter which is a callback of the invoking controller.

The invoking controller creates a private instance of the Get_Data_from_DB function and triggers a request providing the callback function.

I’ll need to test this with parallel queries, but that is still a long way to go…



Source: stackoverflow