How to handle error in angular-ui-router's resolve

前端 未结 2 1881
闹比i
闹比i 2020-12-13 17:28

I am using angular-ui-router\'s resolve to get data from server before moving to a state. Sometimes the request to the server fails and I need to inform the use

相关标签:
2条回答
  • 2020-12-13 18:00

    Old question but I had the same problem and stumbled on this in ui-router's FAQ section

    If you are having issues where a trivial error wasn't being caught because it was happening within the resolve function of a state, this is actually the intended behavior of promises per the spec.

    errors within resolve.

    So you can catch all resolve errors in the run phase of your app like this

    $rootScope.$on('$stateChangeError', 
    function(event, toState, toParams, fromState, fromParams, error){ 
            // this is required if you want to prevent the $UrlRouter reverting the URL to the previous valid location
            event.preventDefault();
            ... 
    })
    
    0 讨论(0)
  • 2020-12-13 18:11

    The issue is that if any of the dependencies in the route resolve is rejected, the controller will not be instantiated. So you could convert the failure to data that you can detect in the instantiated controller.

    Example Pseudocode:-

       data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
          return $timeout(function () { //timeout already returns a promise
            //return "Yes";
            //return success of failure
             return success ? {status:true, data:data} : {status:false}; //return a status from here
           }, 2000);
         }]
    

    and in your controller:-

     controller: ["$scope", "data", "$state", function ($scope, data, $state) {
          //If it has failed
          if(!data.status){
            $scope.error = "Some error";
           return;
          }
            $scope.detailvm = {
              state: $state.current.name,
              data: data
            };
    

    If you are making an $http call or similar you can make use of http promise to resolve the data always even in case of failure and return a status to the controller.

    Example:-

    resolve: {
            data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
               return $http.get("someurl")
                 .then(function(){ return {status:true , data: "Yes"} }, 
                        function(){ return {status:false} }); //In case of failure catch it and return a valid data inorder for the controller to get instantated
            }]
          },
    

    "use strict";
    
    angular.module('MyApp', ["ui.router"]).config([
      "$stateProvider",
      "$urlRouterProvider",
      function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/item");
        $stateProvider
        .state("list", {
          url: "/item",
          template: '<div>{{error}}</div><div>{{listvm}}</div>' +
          	'<a ui-sref="list.detail({id:8})">go to child state and trigger resolve</a>' +
            '<ui-view />',
          controller: ["$scope", "$state", function($scope, $state){
           $scope.listvm = { state: $state.current.name };
          }]
        })
        .state("list.detail", {
          url: "/{id}",
          template: '<div>{{detailvm}}</div>',
          resolve: {
            data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
               return $http.get("/").then(function(){ return {status:true , data: "Yes"} }, function(){ return {status:false} })
            }]
          },
          controller: ["$scope", "data", "$state", function ($scope, data, $state) {
       
        
            $scope.detailvm = {
              state: $state.current.name,
              data: data.status ? data :"OOPS Error"
            };
            
          }]
        });
      }
    ]);
     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
        <script data-require="angular-ui-router@*" data-semver="0.2.10" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
      <div ng-app="MyApp">
          <ui-view></ui-view>
        </div>

    0 讨论(0)
提交回复
热议问题