0

新しいプロジェクトの1つで、httpコールにAngularJS $リソースを使用しています。私はインターネット接続がないときにローカルデータ(SQLiteから)を表示する必要があります。

私は、次の手順で自分の障害をクラスタ化し、ダウン

  • ステップ1以下のサンプルコードを作成しました:ボタンをクリックするだけで
  • ステップ2を完了$リソース//を呼び出します。完了マシンが ネットワークに接続されている場合は、要求のチェックを//送信する前
  • ステップ3:ネットワークが接続されている場合は、
  • を完了応答を//取得
  • ステップ4:なしネットワークは、その後
  • ステップ5 Doneを要求//中止しない場合:なしネットワークが$リソース約束にローカルデータを応答しない場合はを - それを行う方法がわかりません。

var servicetest = angular.module('servicetest', ['ngResource']) 
 
.factory('interceptors' ,function($rootScope, offlineCntrl){ 
 
    return { 
 
     'request':function(request){ 
 
     if(!offlineCntrl.isOnline()){ 
 
      //there wont be a server call 
 
      request.url=''; 
 
      //Abort the request 
 
      request.timeout; 
 
     }else{ 
 
      return request; 
 
     } 
 
     }, 
 
    
 
    'response':function(response){ 
 
     if(!offlineCntrl.isOnline()){ 
 
      offlineCntrl.assignLocal(request).then(function(data){ 
 
      //Get the local data here. 
 
      // Have to pass this data to my response 
 
      // At this stage I am getting an error attached below 
 
      response.data = data; 
 
      return response; 
 
      }) 
 
      
 
     }else{ 
 
     return response; 
 
     } 
 
    } 
 
    } 
 
}) 
 
.config(function($httpProvider){ 
 
    $httpProvider.interceptors.push('interceptors'); 
 
}) 
 
.factory('offlineCntrl', function($q, $timeout){ 
 
    return { 
 
    isOnline: function(){ 
 
     return navigator.onLine; 
 
    }, 
 
    assignLocal:function(request){ 
 
     var defer = $q.defer(); 
 
     $timeout(function(){ 
 
     defer.resolve({title:"local", body:"Local local data context"}); 
 
     }) 
 
     return defer.promise; 
 
    } 
 
    } 
 
}) 
 
.factory('CloudSerivce', function($resource){ 
 
    return $resource('https://jsonplaceholder.typicode.com/posts/:id', { 
 
    id:'@id' 
 
    }, { 
 
    get:{ 
 
     method:"GET", 
 
\t \t \t isArray:false, 
 
\t \t \t cancellable: true 
 
    } 
 
    }) 
 
}) 
 
.controller('mainCntrl', function($scope, CloudSerivce){ 
 
    $scope.data = {}; 
 

 
    $scope.getCloudService = function(){ 
 
    CloudSerivce.get({id:1}).$promise.then(function(data){ 
 
     //It should receive local data if there is no network 
 
     $scope.data = data; 
 
    }, function(err){ 
 
     console.log(err) 
 
    }) 
 
    } 
 

 
})
<html ng-app="servicetest"> 
 
    <body ng-controller='mainCntrl'> 
 
    <h1>{{data.title}}</h1> 
 
    <p>{{data.body}}</p> 
 
    <button ng-click='getCloudService()'> 
 
     GET ITEMS 
 
    </button> 
 
    <h4>Try the button disabling your internet connection</h4> 
 
    </body> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js"></script> 
 
</html>

私は繰延約束イベントに応答を返すようにしようとしたとき、私はエラーを取得しています。

TypeError: Cannot read property 'headers' of undefined 
at f (angular.js:7520) 
at C (angular.js:10924) 
at angular.js:11010 
at h.$eval (angular.js:11930) 
at h.$digest (angular.js:11756) 
at a.$apply (angular.js:12036) 
at HTMLButtonElement.<anonymous> (angular.js:17871) 
at angular.js:2612 
at q (angular.js:309) 
at HTMLButtonElement.c (angular.js:2611) 

私は、$ rootScopeエミッタをバブルアップし、コントローラの中でそれをキャッチすることにより、それを行うことができますが、私は最も簡単な方法は、ngResource(CloudService $の約束イベント)要求を中断した後、応答をハックすることであると信じています。 オフラインとオンラインモードで動作するコントローラgetCloudServiceをそのまま使用できるようにします。

答えて

1

その

.factory('interceptors' ,function($rootScope, offlineCntrl){ 
     return { 
      'request':function(request){ 
      if(!offlineCntrl.isOnline()){ 
       //there wont be a server call 
       request.url=''; 
       //Abort the request 
       request.timeout; 
      }else{ 
       return request; 
      } 
      }, 

      'response':function(response){ 
      const deferred = $q.defer(); 
      if(!offlineCntrl.isOnline()){ 
       offlineCntrl.assignLocal(request).then(function(data){ 
       deferred.resolve(data); 
       }); 

      }else deferred.resolve(response); 
      return deferred.promise; 
      } 
     } 
     }) 
+0

正確な解決策を持っているとしてこれらの答えを承認する – kishorekumaru

1

ここに間違いをしました!

$scope.getCloudService = function(){ 
    CloudSerivce.get({id:1}).$promise.then(function(response){ 
     //It should receive local data if there is no network 
     $scope.data = response.data;//modified 
    }) 
    } 

エラーケースを処理するには、このようなsomehtingを使用する必要がありますか?

$scope.getCloudService = function(){ 
     CloudSerivce.get({id:1}).$promise.then(function(response){ 
      //It should receive local data if there is no network 
      $scope.data = response.data;//modified 
     }),function(error){ 
      //ERROR HANDLING 
     }); 
} 
+0

のような何かをする必要があり、私はスニペットを変更したが、ここでのポイントは$タイムアウトを使用してHTTPインターセプタからの応答をオーバーライドする方法です。 – kishorekumaru

+0

はオーバーライドを意味しますか?特定の時間制限付きで** $ scope.data **をリフレッシュしたい – Aravind

+0

$ scope.dataを期限切れで正確にリフレッシュしていません。工場のインターセプタの応答は$ timeoutで約束を解決するはずです。スニペットを修正しました。インターネット接続を無効にしてテストすることができます。 – kishorekumaru

0

次の回避策がありました。

var servicetest = angular.module('servicetest', ['ngResource']) 
 
.factory('interceptors' ,function($rootScope, offlineCntrl, $q){ 
 
    return { 
 
     'request':function(request){ 
 
     if(!offlineCntrl.isOnline()){ 
 
      //there wont be a server call 
 
      request.url=''; 
 
      //Abort the request 
 
      request.timeout; 
 
     }else{ 
 
      return request; 
 
     } 
 
     }, 
 
    
 
    'response':function(response){ 
 
     if(!offlineCntrl.isOnline()){ 
 
      var deferred = $q.defer(); 
 
      offlineCntrl.assignLocal(request).then(function(data){ 
 
      //Get the local data here. 
 
      // Have to pass this data to my response 
 
      // At this stage I am getting an error attached below 
 
      response = data; 
 
      return deferred.resolve(response); 
 
      }) 
 
      return (deferred.promise); 
 
     }else{ 
 
     return response; 
 
     } 
 
    } 
 
    } 
 
}) 
 
.config(function($httpProvider){ 
 
    $httpProvider.interceptors.push('interceptors'); 
 
}) 
 
.factory('offlineCntrl', function($q, $timeout){ 
 
    return { 
 
    isOnline: function(){ 
 
     return navigator.onLine; 
 
    }, 
 
    assignLocal:function(request){ 
 
     var defer = $q.defer(); 
 
     $timeout(function(){ 
 
     defer.resolve({title:"local", body:"Local local data context"}); 
 
     }) 
 
     return defer.promise; 
 
    } 
 
    } 
 
}) 
 
.factory('CloudSerivce', function($resource){ 
 
    return $resource('https://jsonplaceholder.typicode.com/posts/:id', { 
 
    id:'@id' 
 
    }, { 
 
    get:{ 
 
     method:"GET", 
 
\t \t \t isArray:false, 
 
\t \t \t cancellable: true 
 
    } 
 
    }) 
 
}) 
 
.controller('mainCntrl', function($scope, CloudSerivce){ 
 
    $scope.data = {}; 
 

 
    $scope.getCloudService = function(){ 
 
    CloudSerivce.get({id:1}).$promise.then(function(data){ 
 
     //It should receive local data if there is no network 
 
     $scope.data = data; 
 
    }, function(err){ 
 
     console.log(err) 
 
    }) 
 
    } 
 

 
})
<html ng-app="servicetest"> 
 
    <body ng-controller='mainCntrl'> 
 
    <h1>{{data.title}}</h1> 
 
    <p>{{data.body}}</p> 
 
    <button ng-click='getCloudService()'> 
 
     GET ITEMS 
 
    </button> 
 
    <h4>Try the button disabling your internet connection</h4> 
 
    </body> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js"></script> 
 
</html>

関連する問題