使用变量在Angular服务中调用API

时间:2015-07-30 05:14:40

标签: javascript angularjs api

我目前正在尝试访问Google Books API,我已成功设法直接在我的控制器中进行访问,但为了最佳实践,我希望将业务逻辑转换为指令。

HTML

<form ng-submit="search(data)">
<div class="list">
  <div class="list list-inset">
    <label class="item item-input">
      <input type="text" placeholder="Search by Book Title" ng-model="data.isbn">
    </label>
  </div>
  <button class="button button-block button-positive" type="submit">
    Find Book
  </button>
</div>

上面我将 data.isbn 附加到 search()函数。

Controller.js

.controller('DashCtrl', function($scope, BookSearch) {
  $scope.search = function(data) {
    $scope.books = BookSearch(data).all();
  };
})

然后我将该参数提供给我的 BookSearch 服务。

Service.js

.factory('BookSearch', function ($http) {

  return function(data) {
    var api = "https://www.googleapis.com/books/v1/volumes?q=" + data;
    // Simple GET request example :
    $http.get(api).
      success(function(data, status, headers, config) {
        var books = data;
      }).
      error(function(data, status, headers, config) {
        console.log(status);
      });

  }

  return {
    all: function() {
      return books;
    }
  }  


});

在services.js中,我希望使用搜索参数从Google访问Books API,然后编写多个函数,其中一个函数是 all(),只需将图书归还给 $ scope.books 。

  • 我收到此错误:
  

TypeError:无法读取未定义的属性“all”

当我尝试在all()函数中进行http调用时,$ http.get甚至不执行,因为我无法记录成功和错误情况,并且$ scope.books仍未定义。

我正在努力坚持使用最佳实践来构建一个整洁且可扩展的应用程序,并以应有的方式学习角度。

我看了很多教程,但他们只使用$ http.get调用静态JSON文件而没有来自用户的参数。

有人可以建议我是否以正确的方式解决这个问题以及我的错误在哪里?

1 个答案:

答案 0 :(得分:0)

认为您无法理解承诺如何在角度中发挥作用。承诺是异步的,所以你不能只做$scope.books = BookSearch(data).all();。您需要等待BookSearch(data).all()的响应,然后在成功回调函数中设置$scope.books。希望这个article会帮助你

将您的服务更改为

.factory('BookSearch', function ($http) {
  return {
    all: function(data) {
      var api = "https://www.googleapis.com/books/v1/volumes?q=" + data;
      // Simple GET request example :
      return $http.get(api).
          success(function(data, status, headers, config) {
            // This is the callback function when the $http.get completes successfully so you can remove it
            return data;
          }).
          error(function(data, status, headers, config) {
            console.log(status);
          });
    }
  }  
});

和您的控制器:

.controller('DashCtrl', function($scope, BookSearch) {
  $scope.search = function(data) {
    BookSearch(data).all().then(function(data) {
        // This is the callback function when BookSearch(data).all completes successfully
        $scope.books = data;
    }
  };
})