angular然后从服务中捕获成功错误

时间:2016-08-28 17:52:39

标签: angularjs promise

我担心我可能已经失去了递归承诺的兔子洞。

我有一个处理我的api的服务。 (它有一个额外的承诺层,以便我可以在api离线时切换回本地json。(不确定它是否有必要) - mayte我应该为了简单而消除它。 然后我在我的控制器中得到了承诺的异步调用。

这一切都很好,只要我得到我期望的数据,但它并没有很好地处理错误。当我收到400和500时,它不会通过toastr向用户发送错误消息。

可悲的是,这不是一个完全兼容的RESTful api。我得到的400错误只是

{"Message":"No packages found"}

我真的不知道如何让它按照应有的方式运行,并用then / catch替换成功/错误(根据Angular最佳实践)。

以下是典型的服务电话:

var _getPackagesPage = function (options) {

    var pageSize = options.data.pageSize;
    var page = options.data.page -1;
    return $q (function(resolve, reject) {
        switch (dataSource) {
            case 'api'://staging - live api data
                return $http({
                    method: 'get',
                    url: serviceBase + 'api/Packages?pageSize=' + pageSize + '&page=' + page
                }).then(function(results) {
                    resolve(results);
                });
                break;

            default: // dev - local json

                $.getJSON('Content/data/Packages.json', function (json) {
                    var pageSize = options.data.pageSize;
                    var page = options.data.page;
                    var newjson = json.splice(page*pageSize,pageSize);
                    resolve(newjson);
                });
        }
    });
};

和控制器中的典型调用:

选项是传回我的数据网格(Kendo)的数据对象)

    vm.getPackages = function(options) {
        return packagesService.getPackagesPage (options)
            .then(function(results) {
                options.success(results.data.Items);
            })
            .catch(function(error) {
                options.error(error);
                toastr.error(error.Message);
            });
    };

我该如何清理它?

[更新]尝试修复每个答案1,

服务:

    var _getOrdersPage = function (options) {

        var deff = $q.defer();
        var pageSize = options.data.pageSize;
        var page = options.data.page -1;
        return $http({
            method: 'get',
            url: serviceBase + 'api/Packages?pageSize=' + pageSize + '&page=' + page
        })
        .then(
            function(results) {
                deff.resolve(results);
            },
            function(ex){ 
                deff.reject(ex);
            });
        return deff.promise;
    };

控制器:

    vm.getOrders = function (options) {
        return ordersService.getOrdersPage (options)
            .then(function(results) {
                console.log("results!");
                console.log(results);
            })
            .catch(function(error) {
                console.log("error!");
                console.log(error);
            });
    };

结果:

  

获取http://< myURL> / api / Packages?pageSize = 20& page = 0 400(错误请求)

     

效果

     

未定义

2 个答案:

答案 0 :(得分:1)

为了简洁,我正在移除开关盒。

var _getPackagesPage = function (options) {

var pageSize = options.data.pageSize;
var page = options.data.page -1;
var deff = $q.defer();

$http({
      method: 'get',
      url: serviceBase + 'api/Packages?pageSize=' + pageSize + '&page=' + page
      }).then(
           function(results) {
              deff.resolve(results);
            },
            function(ex){ 
              deff.reject(ex);
             });

 return deff.promise;
    };

控制器

vm.getOrders = function (options) {
    return ordersService.getOrdersPage (options)
        .then(
         function(results) {
            console.log("results!");
            console.log(results);
        },
        function(error) {
            console.log("error!");
            console.log(error);
        });
};

如果您的服务中没有任何逻辑,那么您可以返回$ http本身,因为$ http inturn是一个承诺:

var _getPackagesPage = function (options) {

  var pageSize = options.data.pageSize;
  var page = options.data.page -1;

   return $http({
        method: 'get',
         url: serviceBase + 'api/Packages?pageSize=' + pageSize + '&page=' + page
      });

    };

答案 1 :(得分:0)

您的服务中有太多退货。第二个没有被调用。

您不需要手动创建承诺,因为$ http会返回apromise。

您没有从服务中返回数据。

function myService($http) {
  this.getData = function(url) {
    return $http.get(url).
    then(function(response) {
      return response.data;
    }, function(error) {
      return error;
    });
  }
};

function MyController(myService) {
  var vm = this;  
  vm.result = [];
  vm.apiUrl = "https://randomuser.me/api/";
  myService.getData(vm.apiUrl).then(function (data) {
    vm.result = data;
  },
  function(error) {
    console.log(error);
  });
};

angular.module('myApp', []);
angular
    .module('myApp')
    .service('myService', myService)
    .controller('MyController', MyController);

您的控制器没问题,您可以使用catch()或传递错误回调。

示例:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyController as ctrl">
    {{ ctrl.result }}
  </div>
</div>
<base>