Reputation: 49
I am developing both a javascript library and an AngularJS front-end. The JavaScript Library needs to be portable so it cannot rely on AngularJS. We use a pretty standard servlet query pattern:
queryService = function(url, method, params, resultHandler, queryId)
{
var request = {
jsonrpc: "2.0",
id: queryId || "no_id",
method: method,
params: params
};
$.post(url, JSON.stringify(request), handleResponse, "json");
function handleResponse(response)
{
if (response.error)
console.log(JSON.stringify(response, null, 3));
else if (resultHandler)
resultHandler(response.result, queryId);
}
};
This queryService
function is called by other functions in our library. You can see that that queryService
returns nothing. It expects the callback function to perform all needed actions. I can't figure out what callback function is needed to return my result to the promise object's then()
function. Here's the Angular service code:
angular.module("app").service("Data", function($q){
return {
getColNamesFromDb: function(table, scope){
var deferred = $q.defer();
var callbackFcn = function(result){
console.log(result); // This successfully logs the result to the console!
deferred.resolve(result); // also tried deferred.resolve();
};
var safeApply = function(scope, fn) {
(scope.$$phase || scope.$root.$$phase) ? fn() : scope.$apply(fn);
};
safeApply(scope, function(){
deferred.resolve(queryWrapperForColNames(scope.tableName, callbackfcn));
// also tried $q.when(queryWrapperForColNames(scope.tableName, callbackfcn));
});
return deferred.promise;
}};
});
From my controller I call Data.getColNamesFromDb()
and get a promise object. But no matter what I try I can't get my then()
function to see what was returned from the DB. Here is the controller:
angular.module("app").controller("Ctrl", function($scope, Data)
{
$scope.options;
var promise = Data.getColNamesFromDb("table1", $scope);
promise.then(function(result){
$scope.options = result;
},function(result){
console.log("error " + result);
});
})
I KNOW I'm missing something stupid about how promises work but I can't see what. It should be clear from some of the "options" I've commented in my code that I'm at the point that I'm just trying random methods and crossing my fingers.
Upvotes: 2
Views: 300
Reputation: 2892
The first thing to try is fixing this call:
var promise = Data.getColNamesFromDb("table1", $scope);
According to your example, that method is defined as taking $scope as the first parameter, not the second, so your safeApply function will never actually cause a $digest cycle to occur since that string doesn't have a $$phase property.
Edit
Now that the example has been corrected, try this:
angular.module( "app" ).service( "Data", function( $q ) {
return {
getColNamesFromDb: function( table, scope ) {
var deferred = $q.defer();
function safeApply( fn ) {
if ( !scope.$$phase ) {
scope.$apply( fn );
}
else {
fn();
}
}
queryWrapperForColNames( scope.tableName, function( result ) {
safeApply(function() {
console.log( result );
deferred.resolve( result );
});
});
return deferred.promise;
}
};
});
In your original example, you're resolving the deferred twice; once in your safeApply call, and once in your callback function. Deferreds can only be resolve once ( further calls have no effect ), so the deferred would have been resolved with the value passed to it in safeApply. Since queryWrapperFor
most likely implicitly returns undefined ( I don't see the definition here ), your deferred would have been resolved with undefined.
Upvotes: 1