0

В одном из моих новых проектов я использую ресурсы AngularJS $ для http-звонков. У меня есть требование показать локальные данные (из SQLite), когда нет подключения к Интернету.

Я группировался мои препятствия следующих шагов, и создал образец коду вниз ниже

  • Шаг 1: по нажатию кнопки колла $ ресурса // Закончил
  • Шаг 2: Перед отправкой проверить запрос, если машина подключен к сети // Закончили
  • Шаг 3: Если сеть подключена, получить ответ // Закончили
  • Шаг 4: Если нет сети, то не прервать запрос // Закончили
  • Шаг 5: Если сеть не отвечают локальные данные в $ ресурсов обещание - Не знаете, как сделать это.

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 
    }) 
    } 

Кроме того, чтобы обработать ошибку, вы должны использовать некоторую проблему как это?

$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>

Смежные вопросы