Domanda

I have created a factory to provide data to my app

myApp.factory('dataRepository', function ($resource) {
return {
   getApplicationErrors: function (applicationName) {

        return $resource('/api/DataSource/GetApplicationErrors').query();
    },
}

I have changed my data access from using $http, $q to use $resource into:

old implementation

 var deffered = $q.defer();

        $http.get('/api/DataSource/GetApplicationErrors').success(deffered.resolve).error(deffered.reject);

        return deffered.promise;

new implementation

  $scope.exceptions  = dataRepository.getApplicationErrors($routeParams.applicationName);

now in case that there is an error while fetching my data I want to display an error.

So when I had old implementation I had two callback to hook up to and now I am not sure how to implement it. My idea was:

myApp.controller("ErrorListController",
function ErrorListController($scope, dataRepository) {

dataRepository.getApplicationErrors('test')
.$promise
    .then(function (data) {
        $scope.exceptions = data;
    }, function(error) {
        $scope.errorMessage = 'Failed to load data from server';
    });

});

Question

What is correct way in hooking up to $resource success / fail?

Possible answer

Add call back functions for success and failure, but I do not consider this as solution.

È stato utile?

Soluzione

The first thing to consider is why are you changing to $resource? The $resource service is supposed to provide a pseudo object-REST mapping. So that you can get hold of objects and collections of objects, which you may wish to modify and save again. If all you want is to have a service that retrieves a collection of errors then it may well be simpler to continue to use $http.

Second, the way to use $resource is to call it once inside your service factory function to create a concrete "typed/bound" resource object, which you then return as your service:

myApp.factory('dataRepository', function ($resource) {
  return {
    getApplicationErrors: $resource('/api/DataSource/GetApplicationErrors')
  };
}

In your controller you can inject this to get access to the resource methods. The first parameter of query is a params object, which basically gets passed straight through to $http. So you can do stuff there...

myApp.controller("ErrorListController",
    function ErrorListController($scope, dataRepository) {

  $scope.errors = dataRepository.getApplicationErrors.query({ params: { appName: 'test' });
};

This will immediately add an empty array to $scope.errors property. When the response arrives, the resource will fill this array with the results.

If you want to catch errors then you can make use of the $promise property on the returned object. This gives you access to the raw $http promise that is being used under the covers:

myApp.controller("ErrorListController",
    function ErrorListController($scope, dataRepository) {

  $scope.errors = dataRepository.getApplicationErrors.query({ params: { appName: 'test' });
  $scope.errors.$promise.then(success, error);
};

Altri suggerimenti

Http interceptors are probably your best bet for wrapping all response errors. It's essentially a way to wrap all of your http calls through angular. You're going to want to do something like this:

.config(function($httpProvider) {
  $httpProvider.interceptors.push('MyInterceptor');
})
.service('MyInterceptor', function($q, $injector) {
  return {
    responseError: function(error) {
      // Maybe you want to persist to database?
      $http = $injector.get('$http');
      $http.post('/log/my/error', error);

      //... Notify the user of the error here or add logic to dynamically propagate to the user
      alert("ERROR: " + error);

      // continue promise chain
      $q.reject(error);
    }
  };
});

Documentation can be found here. In the http interceptors section.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top