robin
robin

Reputation: 1925

Issue with Angular Js resolve method

Hi I have a $stateProvider like below.

$stateProvider .state('team.details', {
  url: '/:teamId',
  views: {
    '@': {
      controller: 'teamDetailsCtrl',
      templateUrl: 'src/modules/team/details/teamDetails.html',
      resolve: {
        user: function ($stateParams, TeamResource) {
          return TeamResource.get({ teamid: $stateParams.teamId }).$promise;
        }

The TeamResource.get is calling a rest api and everything is working fine if the data is sent from the rest api(teamid present in DB). But if the data is not present then I have to route it to a "home". How can i accomplish it ?

Upvotes: 2

Views: 38

Answers (3)

Ashish Kumar
Ashish Kumar

Reputation: 3039

Angular $http.get() returns a promise itself. if case of any error, you just need to reject the same with $q service.

In resolve:

resolve : {
    user : function ($stateParams, TeamResource) {
        return TeamResource.get({
            teamid : $stateParams.teamId
        });
    }
}

Under TeamResource.get:

return {
    get : function (teamObj) {
        $http.get("/url", teamObj).then(function (resp) {
            if (resp.length) {
                return resp;
            } else {
                return $q.reject(resp);
            }
        }, function (err) {
            return $q.reject(resp);
        });
    }
}

In case of return in promise() with $q.reject(), the promise chain sends it to error callback to the next chain and if you just return with something, it sends it to success function in next promise chain.

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136184

You resolve could handle that thing, if data is there then return that data using chain promise or else redirect the to different state.

Code

resolve: {
  user: function($stateParams, TeamResource, $state) {
    return TeamResource.get({
      teamid: $stateParams.teamId
    }).$promise.then(function(data) {
      if (!data.length > 0) { //here might be you need to use something else instead of data
        $state.go('home')
        return
      } else {
        return data;
      }
    });
  }

Upvotes: 2

Erik Svedin
Erik Svedin

Reputation: 1286

What kind of response does your API return? My suggestion is that you set up a global http interceptor for your app which could listen to 404 responses. And in that case redirect users to your home state.

By putting the logic in an interceptor instead of the resolve, you can avoid redundant code if you have several states which may benefit from this kind of check.

This is an example interceptor, taken from this SO post.

Note that this may only be wanted for a specific endpoint (eg the teams). You can check which url got called by accessing the url property of response. Like so: response.url

var interceptor = ['$q', '$state', function ($q, $state) {

    function success(response) {
        return response;
    }

    function error(response) {
        var status = response.status;
        var url = response.url;

        if (status == 404) {
            $state.go('home')
            return;
        }

        // otherwise
        return $q.reject(response);
    }

    return function (promise) {
        return promise.then(success, error);
    }

}];

$httpProvider.responseInterceptors.push(interceptor);

Upvotes: 0

Related Questions