aplon aplon - 10 days ago 6
AngularJS Question

Angular promise resolved before factory execution

We are trying to update a Factory which returns a promise. The original Factory uses $http->success->error and the controller has a .then(...).

We want to "migrate" from success/error to then/catch, but we get the following error message in the controller:

TypeError: Cannot read property 'then' of undefined
.

The Factory methods are the following ():

'use strict';
xmsbsExtranet.factory('projectsTimeTrackingServices', ['$resource', '$http', '$log', '$q', 'membershipServices',
function ($resource, $http, $log, $q, membershipServices) {
var serviceBase = 'http://localhost:51617/api/';
var _model = {};

var service = {
model: _model,
getByProjectId: _getByProjectId_new,
upsert: _upsert,
};
return service;

function _getByProjectId_old(projectId) {
var deferred = $q.defer();
$http({
method: "Get",
url: "../api/projectsTimeTracking/project/" + projectId
}).success(function (response) {
deferred.resolve(response);
}).error(function (err, status) {
//membershipServices.logOut();
deferred.reject(err);
});

return deferred.promise;
};

function _getByProjectId_new(projectId) {
$http.get("../api/projectsTimeTracking/project/" + projectId)
.then(function (response) {
return response.data;
}).catch(function (err, status) {
//membershipServices.logOut();
return err;
});
};

}]);


The "short" version of the controller is as follows:

projectsTimeTrackingServices
.getByProjectId(vm.project.xrmId)
.then(function (data) {
//do something with the data
});


When the service executes the method "_getByProjectId_old", everything Works as expected. But if I change it to "_getByProjectId_new", I get the afformentioned error.

Any Help will be greatly appreciated.
Best regards

Answer

Correct me if I'm wrong - but you're not actually returning anything from the 'new' version of this function.

    function _getByProjectId_new(projectId) {

        //note that nothing is returned in THIS scope.

        $http.get("../api/projectsTimeTracking/project/" + projectId)
        .then(function (response) {
            return response.data;
        }).catch(function (err, status) {
            //membershipServices.logOut();
            return err;
        });
    };

You can fix this by using this code:

    function _getByProjectId_new(projectId) {

        //note the new return statement
        return $http.get("../api/projectsTimeTracking/project/" + projectId)
    };

or this code (depending on whether you want to return 'response' or 'response.data'):

    function _getByProjectId_new(projectId) {

        //note the new return statement
        return $http.get("../api/projectsTimeTracking/project/" + projectId)
           .then(function (response) {
               return response.data;
            });
    };

I'd refrain from catching the error within this function, since if you catch the error, your controller code will not be able to catch it.

You should probably read some documentation on promises and then/catch chaining, it's a little tricky.

Comments