Angular, then catch the success error from services

I'm afraid I may have lowered the rabbit hole of recursive promises.

I have a service that processes my api. (He got an extra level of promise so that I could go back to the local json if the api disconnected. (Not sure how this is needed anymore) - may I have to fix it for simplicity). Then I have the promised asynchronous call in my controller.

All this works fine as long as I get the data that I expect, but it does not handle errors very well. When I get 400 and 500, it does not send an error message to the user via toastr.

Unfortunately, this is not a fully compatible RESTful api. The 400 error that I am returning is simply

{"Message":"No packages found"}

I really don't understand how to make this behave as it should and replace success / error with / catch (according to Angular's best practice).

Here is a typical office call:

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

and a typical call in the controller:

( parameters is a data object passed to my data grid (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);
            });
    };

How can i clear this?

[UPDATE] Attempted correction for answer 1, below

Services:

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

Controller:

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

leads to:

GET http: // <myURL> / api / Packages? pageSize = 20 & page = 0 400 (failed request)

results!

undefined

+4
source share
2 answers

I remove the switch case for brevity.

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

controller

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

If you don't have any logic inside your service, then you can return $ http, since $ http inturn is a promise:

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

. .

, $http apromise.

.

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() .

:

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);
<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>
Hide result
0

Source: https://habr.com/ru/post/1652767/


All Articles