TypeError: Cannot read property '$promise' of undefined with using ngResource in angularJS

TypeError: Cannot read property '$promise' of undefined with using ngResource in angularJS

我在我的 angularJS 应用程序中使用 ngResource 创建了一个服务,用于将一些数据发送到我的其余部分 api。

我想在发送请求后立即在我的控制器中使用承诺来执行一些任务。

这是我的服务:

angular.module("MyService", ['ngResource'])

.factory("myService",  function ($rootScope, $http, $resource) {

    var apiData = $resource(
        "/api", {},
        {

                  "postQuestion": { method: "POST", url: "/api/:userid"}

        });

        return {

            postQuestion: function(question,  user_id) {
                apiData.postQuestion({ userid: user_id}, question, function(data) {
                    console.log("Sucsess !");
                }, function(error) {
                    console.log("Error " + error.status + " when sending request : " + error.data);
                });

            }
    }
});

这是我在控制器中使用它的方式:

app.controller("MyCtrl", function ($scope, $filter,  $http, $sce, myService, ngDialog, $rootScope, $location) {


$scope.postQuestion = function(newQuestion)
{

    myService.postQuestion(newQuestion, 1).$promise.then(function(){
        $scope.showNewQuestion = false;
        $location.path("/");
    });
}


})

但是当 运行 我的应用程序时,我的控制台出现了这个错误:

TypeError: Cannot read property '$promise' of undefined at Scope.$scope.postQuestion ...

不知道为什么,求助

myService 中的这个函数不是 return 承诺:

postQuestion: function(question,  user_id) {
    apiData.postQuestion({ userid: user_id}, question, function(data) {
        console.log("Sucsess !");
    }, function(error) {
        console.log("Error " + error.status + " when sending request : " + error.data);
    });
}

然而控制器中的调用代码需要一个:

myService.postQuestion(newQuestion, 1).$promise.then(function(){
    $scope.showNewQuestion = false;
    $location.path("/");
});

要修复,您可以使用 $q 库创建自己的承诺,然后根据需要解决或拒绝它,然后 return 向控制器承诺:

postQuestion: function(question,  user_id) {
    var deferred = $q.defer();
    apiData.postQuestion({ userid: user_id}, question, function(data) {
        console.log("Sucsess !");
        deferred.resolve(data);
    }, function(error) {
        console.log("Error " + error.status + " when sending request : " + error.data);
        deferred.reject(error);
    });
    return defered.promise;
}

然后你可以从调用代码中删除$promise并在myService.postQuestion的return值上调用then函数(现在是一个承诺):

myService.postQuestion(newQuestion, 1).then(function(){
    $scope.showNewQuestion = false;
    $location.path("/");
});

postQuestion 函数缺少 return 语句:

    postQuestion: function(question,  user_id) {
        //vvvv RETURN the resource object
        return apiData.postQuestion({ userid: user_id}, question, function(data) {
            console.log("Sucsess !");
        }, function(error) {
            console.log("Error " + error.status + " when sending request : " + error.data);
        });

    }

当函数省略 return 语句时,它 returns 的值为 undefined。因此错误消息:

TypeError: Cannot read property '$promise' of undefined at ...

没有必要使用 $q.defer() 作为 $resource 服务来制造承诺,因为已经 returns 作为 $promise 属性 附加到资源对象的承诺。

The Resource instances and collections have these additional properties:

  • $promise: the promise of the original server interaction that created this instance or collection.

On success, the promise is resolved with the same resource instance or collection object, updated with data from server. This makes it easy to use in resolve section of $routeProvider.when() to defer view rendering until the resource(s) are loaded.

On failure, the promise is rejected with the http response object, without the resource property.

If an interceptor object was provided, the promise will instead be resolved with the value returned by the interceptor.

-- AngularJS $resource API Reference