Search code examples
routesangular-ui-routerrestangular

Resolve error not working


I'm using ui.router and Restangular. In $stateProvider I have state with

resolve: {
    dane: function (daneTematy) {
        var promise = daneTematy.getItem(-1);
        return promise;
    }
}

For tests it always gest error and execute $stateChangeError

Here is func from service:

function getItem(id, params) {
    return Restangular.one(zrodlo, id).get()
        .then(getItemSuccess)
        .catch(restangularError);

    function getItemSuccess(response) {
        $log.info('Mam dane elementu - Źródło: ' + zrodlo);
        response.doHistorii();
        return response;
    }
}

function restangularError(response) {
    $log.error("Error with status code", response.status);
    return response;
}

It's not working - it gets to restangularError but not to $stateChangeError. When I delete catch it works well:

function getItem(id, params) {
    return Restangular.one(zrodlo, id).get()
        .then(getItemSuccess);

    function getItemSuccess(response) {
        $log.info('Mam dane elementu - Źródło: ' + zrodlo);
        response.doHistorii();
        return response;
    }
}

What is a problem with restangularError? How to fix it?


Solution

  • Within your error handler, you mark the error as being resolved. So ui-router gets a resolved promise and therefore does not cause a $stateChangeError. To solve this, you have to reject a promise within an error handler if you couldn't fix it. See this excerpt from the angular documentation:

    When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of reject as the throw keyword in JavaScript. This also means that if you "catch" an error via a promise error callback and you want to forward the error to the promise derived from the current promise, you have to "rethrow" the error by returning a rejection constructed via reject.

    promiseB = promiseA.then(function(result) {
      // success: do something and resolve promiseB
      //          with the old or a new result
      return result;
    }, function(reason) {
      // error: handle the error if possible and
      //        resolve promiseB with newPromiseOrValue,
      //        otherwise forward the rejection to promiseB
      if (canHandle(reason)) {
       // handle the error and recover
       return newPromiseOrValue;
      }
      return $q.reject(reason);
    });
    

    For your case this just means you have to modify your error handler as follows (make sure $q is available):

    function restangularError(response) {
        $log.error("Error with status code", response.status);
        return $q.reject(response);
    }