【问题标题】:AngularJS factory retuning undefined object from $httpAngularJS 工厂从 $http 重新调整未定义的对象
【发布时间】:2018-09-02 10:57:47
【问题描述】:

我在工厂中使用$http 指令从我的AngularJS 应用程序进行API 调用(我已经尝试了$http$resource,我并不关心我使用哪个,只要它返回数据),当我不使用.then() 来解开承诺或undefined 时,我得到一个$$state 对象。

这是工厂的代码:

app.service('dataService', ['$http', function($http) {
    return {
        quizQuestions: function() {
            return $http.get("http://localhost:59143/api/Questions")
                .then(function(response) {
                     console.log(response);
                     console.log(response.data);
                     console.log(response.data[0]);
                     return response;
                })
        }
    }
}])

当我从控制器调用它时,我会这样做:

app.controller('QuizController', ['$scope', '$http', 'dataService', function($scope, $http, dataService) {
    dataService.quizQuestions().then(function(data) {
        $scope.quizQuestions=data;
        console.log($scope.quizQuestions);
    })
}])

此时,我什至没有尝试将数据绑定到视图,而只是观察控制台输出。我在控制台中使用此配置得到的是:

{data: array(1), status: 200, heders: f, config: {...}, statusText: "OK"}
[{...}]
{Text: "...", *rest of object omitted for brevity but it is here*}
undefined

谁能告诉我我做错了什么?

顺便说一句,当我一起消除工厂并将代码放在控制器中时:

app.controller('QuizController',['$scope', '$http', function($scope, $http) {
    $http.get("http://localhost:59143/api/Questions").then(function(response) {
        console.log(response);
        console.log(response.data);
        console.log(response.data[0]);
        $scope.quizQuestions=response.data;
        console.log($scope.quizQuestions);
        console.log($scope.quizQuestions[0]);
    })
}])

我得到以下控制台输出:

{data: array (etc)}
[{...}]
{text: (rest of obj)}
[{...}]
{text: (rest of obj)}

所以它似乎是工厂里的东西?

我查看了这些其他文章以获得一些方向和角度文档,但无济于事。

【问题讨论】:

  • 不是重复的,事后尝试了 .then() ,这就是我遇到问题的时候。如果我只是执行以下操作,我可以获得完整的 http 对象:$scope.quizQuestions=dataService.quizQuestions()。只有当我执行 .then() 时,我才会得到未定义。
  • 现在您的代码似乎没问题。如果可能,请尝试创建 Minimal, Complete, and Verifiable example 以重现错误。

标签: javascript angularjs api


【解决方案1】:

在你的服务中,你已经解开了 $http 返回的承诺。

不管怎样,

...
quizQuestions: function() {
  return $http.get("http://localhost:59143/api/Questions");
}
...

在您的服务中使用 .then() 但返回这样的承诺,

但不要忘记添加 $q 作为依赖项

quizQuestions: function() {
  let defer = $q.defer();
  $http.get("http://localhost:59143/api/Questions").then(function(response) {
  // ...
  defer.resolve(response); // or whatever you want to return
  }, function (error) {
    defer.reject(error);
  })
return defer.promise;
}

所以基本上在你的服务中,你解开承诺,然后返回一个静态值。

现在在您的控制器中,您正在调用您的服务并尝试将 then() 应用于不返回承诺的函数。

【讨论】:

  • $http 已经返回了一个承诺,使用 $q 是一种反模式,don't use them
  • @AlekseySolovey 你是对的,这就是为什么第一个选项,只是返回 $http 的响应。但是如果我们必须处理响应数据然后返回一个 Promise,我们必须使用 $q 或 Promise()。
  • BTW '...' 在第二部分表示处理部分。
【解决方案2】:

data 作为response 对象的属性附加:

app.controller('QuizController', ['$scope', '$http', 'dataService', function($scope, $http, dataService) {
    dataService.quizQuestions().then(function( ̶d̶a̶t̶a̶ response) {
        ̶$̶s̶c̶o̶p̶e̶.̶q̶u̶i̶z̶Q̶u̶e̶s̶t̶i̶o̶n̶s̶=̶d̶a̶t̶a̶;̶
        $scope.quizQuestions=response.data;
        console.log($scope.quizQuestions);
    })
}])

来自文档:

$http 退货

Promise 将通过响应对象解决(请求成功)或拒绝(请求失败)。

响应对象具有以下属性:

  • 数据{string|Object} – 使用转换函数转换的响应正文。
  • status{number} – 响应的 HTTP 状态代码。
  • headers{function([headerName])} – Header getter 函数。
  • config{Object} – 用于生成请求的配置对象。
  • statusText{string} – 响应的 HTTP 状态文本。
  • xhrStatus{string} – XMLHttpRequest 的状态(completeerrortimeoutabort)。

-— AngularJS $http Service API Reference - Returns.

【讨论】:

    猜你喜欢
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多