TypeError:使用angularJS

时间:2017-02-05 01:06:03

标签: angularjs rest promise factory ngresource

我使用ngResource在angularJS应用中创建了一个服务,将一些数据发送到我的rest 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:无法读取undefined的属性'$ promise'       在Scope。$ scope.postQuestion ...

不知道为什么,请帮忙

2 个答案:

答案 0 :(得分:2)

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语句时,它返回值undefined。因此错误消息:

  

TypeError:无法读取属性' $ promise' undefined的...... {/ p>

无需使用$q.defer()生成承诺,因为$ resource服务已经将附加到资源对象的承诺作为$promise属性返回。

  

资源实例和集合具有以下附加属性:

     
      
  • $promise:创建此实例或集合的原始服务器交互的承诺。
  •   
     

成功时,使用相同的资源实例或集合对象解析promise,并使用来自服务器的数据进行更新。这使得在$routeProvider.when()的解析部分中使用它很容易推迟视图渲染,直到资源被加载。

     

失败时,使用http response对象拒绝承诺,但没有资源属性。

     

如果提供了拦截器对象,则将使用拦截器返回的值来解析promise。

     

-- AngularJS $resource API Reference

答案 1 :(得分:1)

myService中的此功能未返回承诺:

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库创建自己的承诺,然后根据需要解析或拒绝它,然后将该承诺返回给控制器:

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并在then的返回值(现在是一个承诺)上调用myService.postQuestion函数:

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