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

Angularjs 然后从服务中捕获成功错误,angularjs,promise,Angularjs,Promise,我担心我可能已经掉进了递归承诺的兔子洞 我有一个处理api的服务。(它有一个额外的承诺层,这样如果api离线,我就可以切换回本地json。(不知道有多大必要了)-为了简单起见,我应该取消它)。 然后我在控制器中得到了承诺的异步调用 只要我得到预期的数据,这一切都非常有效,但它不能很好地处理错误。当我得到400和500时,它不会通过toastr向用户发送错误消息 遗憾的是,这不是一个完全兼容的RESTful api。我得到的400个错误很简单 {"Message":"No packages fou

我担心我可能已经掉进了递归承诺的兔子洞

我有一个处理api的服务。(它有一个额外的承诺层,这样如果api离线,我就可以切换回本地json。(不知道有多大必要了)-为了简单起见,我应该取消它)。 然后我在控制器中得到了承诺的异步调用

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

遗憾的是,这不是一个完全兼容的RESTful api。我得到的400个错误很简单

{"Message":"No packages found"}
我真的不知道如何让它按应有的方式运行,并用then/catch(根据最佳实践)替换success/error

以下是一个典型的服务呼叫:

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);
                });
        }
    });
};
以及控制器中的典型调用:

    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);
            });
    };
选项是返回到我的数据网格(Kendo)的数据对象)

我该怎么清理

[UPDATE]根据下面的回答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:///api/Packages?pageSize=20&page=0400(错误请求)

结果

未定义


为了简洁起见,我正在拆下开关盒

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
      });

    };

你的服务回报太多了。第二个不叫

您不需要手动创建承诺,因为$http返回一个promise

您没有从服务返回数据

var _getOrdersPage = 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
        })
        .then(
            function(results) {
                return results;
            },
            function(ex){
                return ex;
            });
}
控制器正常,可以使用catch()或传递错误回调

例如:

功能myService($http){
this.getData=函数(url){
返回$http.get(url)。
然后(功能(响应){
返回响应数据;
},函数(错误){
返回误差;
});
}
};
功能MyController(myService){
var vm=这个;
vm.result=[];
vm.apiUrl=”https://randomuser.me/api/";
getData(vm.apiUrl).then(函数(数据){
vm.result=数据;
},
函数(错误){
console.log(错误);
});
};
角度模块('myApp',[]);
有棱角的
.module('myApp')
.service('myService',myService)
.controller(“MyController”,MyController)

{{ctrl.result}

清理什么?你能问一个简单的问题吗?我希望能。必须有一种正确的方法来使用服务,进行$http调用并返回结果/错误。不是这样。您可以使用
$http
加载JSON。只是说…是的,避开这个!我希望我能很好地理解一个模式,更不用说反模式了,更不用说把它分成两个模块了。这似乎让我的控制器获得了成功,即使它是400。因此options.success(results.data.Items)返回data=undefined。当您的服务返回400时,将返回.then方法的错误回调,我们从中拒绝承诺。这不会到达您在控制器中的成功回调,而是会命中错误callbacj。但事实并非如此。我已经在开场白中添加了尝试修复和结果。你能验证它是否符合deff.reject(ex);在服务中?它确实达到了deff.reject。ex包含状态:400,状态消息:“错误请求”。