When I tried to return a $http.post() object from a factory function with Angular, it throws me this error:
Below is my code:
AngularUtils.js
Fenrir.factory('AngularUtils', function ($http, $log, $window) {
var AngularUtils = {
save: function(url, obj, errors, not_show_error_toast) {
not_show_error_toast = typeof not_show_error_toast !== 'undefined' ? not_show_error_toast : false;
loaderShow();
if (angular.isDefined(obj.id)) {
return $http.put(url + obj.id + '/', obj).
then(function onSuccess(response) {
loaderHide();
angular.extend(obj, response);
errors = {};
}), function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
};
} else {
return this.create(url, obj, errors, not_show_error_toast);
}
},
create: function(url, obj, errors, not_show_error_toast) {
not_show_error_toast = typeof not_show_error_toast !== 'undefined' ? not_show_error_toast : false;
return $http.post(url, obj).
then(function onSuccess(response) {
loaderHide();
angular.extend(obj, response);
errors = {};
}), function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
};
},
}
return AngularUtils
})
Admin.js
var Fenrir = angular.module('Fenrir', []);
Fenrir.controller('AdminController', function ($scope, $http, AngularUtils) {
$scope.createScreen = function () {
AngularUtils.save('/admin/saveScreen', $scope.record, '', '').then(function (hubs) {
$scope.hubs = hubs;
console.log('In ctrl ' + $scope.hubs);
});
}
})
How do I return the $http.post() object properly?
Looking closely at the error message:
This is saying that there is no function named
then()
that is returned fromAngularUtils.save(...)
. Which indicates that thesave()
function did execute, but it did not return a promise as expected.So your factory method did execute, but because you did not return a promise we can only speculate as to which of the pathways the execution finally resulted in.
Update: syntax error in original script
In trying to justify my solution for you, I found that your
$put().then()
response handler had a syntax issue, there was a bracket in the wrong place, theonError
function is supposed to be the second argument to thethen
function, not after it. Your code should look like this:Subtle, but important, if you do not have strict compilation on, then the factory function was simply not compiled correctly, which could cause your error.
In factory methods where one or some pathways will return async promise deferrals (futures) then the default pattern, although verbose, is to return a single deferral wrapped around the whole method execution, then for each of the response pathways you can choose to resolve or reject the response through the original promise that was returned from the function.
there are different libraries and techniques to do this, see AngularJs and Promises with the $http Service by Rick Strahl for a walkthrough of the common implementations.