2015-04-06 4 views
0

вот часть кода, с которой я борюсь - у меня есть контроллер (zmApp.MonitorCtrl), который вызывает фабрику (ZMFactory) с HTTP-запросом.Обработка обещаний AngularJS с http

Проблема я столкнулся это: а) Когда контроллер вызывает ZMFactory.getMonitors() возвращает неопределенное значение, и я получаю сообщение об ошибке ОШИБКА: Ошибка: не определено не является объектом (оценка «ZMFactory.getMonitors() .then ')

б) После того, как эта ошибка возникает, запрос HTTP на заводе перерабатывается

Я немного запутался. Можете ли вы проверить, правильно ли настроен завод, чтобы вернуть обещание?

var app = angular.module('zmApp.controllers'); 
 

 
app.controller('zmApp.MonitorCtrl', function($ionicPlatform, $scope,$http,ZMFactory) 
 
{ 
 
      
 
      $scope.monitors=[]; 
 
      console.log("***CALLING FACTORY"); 
 
      ZMFactory.getMonitors().then(function(data) 
 
      { 
 
       $scope.monitors = data; 
 
       console.log ("I GOT " +$scope.monitors); 
 
      }); 
 
       
 
}); 
 

 

 

 
app.factory('ZMFactory',['$http', '$rootScope',function($http,$rootScope) 
 
{ 
 
    //var factory = {}; 
 
    var monitors =[]; 
 
    return { 
 
     getMonitors: function() 
 
     { 
 
      console.log("***MAKING REQUEST"); 
 
      $http({ 
 
        url:'http://myurl.com:9999/zm/index.php?skin=xml', 
 
        method:'post', 
 
        headers: {'Content-Type': 'application/x-www-form-urlencoded', 
 
           'Accept': '*/*', 
 
           }, 
 
         transformRequest: function(obj) { 
 
           var str = []; 
 
           for(var p in obj) 
 
           str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 
 
           var foo= str.join("&"); 
 
           console.log ("****RETURNING "+foo); 
 
           return foo; 
 
         }, 
 
         transformResponse: function(data) 
 
         { 
 
          var x2js = new X2JS(); 
 
          var json = x2js.xml_str2json(data); 
 
          console.log ("***Transmogrifying XML to JSON"); 
 
          return json; 
 
         }, 
 
         data: {username:'xxx', 
 
           password:'xxxx', 
 
           action:'login', 
 
           view:'console'} 
 
           
 
         }) //http 
 
         .success (function(data) 
 
         { 
 
          console.log("****YAY"+JSON.stringify(data)); 
 
            
 
          var subobj =data.ZM_XML.MONITOR_LIST.MONITOR; 
 
          var len = subobj.length; 
 
          for (var i =0; i< len; i++) 
 
          { 
 
          console.log ("HERE " + subobj[i].NAME); 
 
          monitors.push(subobj[i]); 
 
          } 
 
          // $rootScope.$broadcast ('handleZoneMinderMonitorsUpdate',monitors); 
 
          return monitors; 
 
         }) //success 
 
         .error(function(data, status, headers, config) 
 
         { 
 
          console.log("***OOPS "+status + " H: "+data); 
 
          return monitors; 
 
         }); 
 

 
     } //getMonitors 
 
    };//return 
 
    console.log ("**** NEVER *****"); 
 
         
 
}]);

+0

вам нужен массив зависимостей для контроллера? – Plato

+0

Привет, Платон, я не уверен, но я так не думаю - завод может быть вызван с контроллера. – user1361529

+0

ах, я вижу, да функция getModules не возвращает обещание. извините, я не знаю, как построить обещание. – Plato

ответ

1

Ключ к ответу в редакции собственного вопроса:

Can you please check if the factory has been set up correctly to return a promise

Вы должны return его. Сейчас ваша getMonitors функция (если удалить весь код отношения к вопросу) выглядит следующим образом:

getMonitors: function(){ 
    $http({}) 
    .success(function(data){ 
     // convert data to monitors 
     return monitors; 
    }); 
} 

Это вызов функции, которая не возвращает ничего, или, вернее, возвращает undefined. Нет никаких «магии» с обещаниями - это как и любой другой объект - вам нужно вернуть его вызывающему.

Итак, две вещи, которые нужно сделать:

1) Изменение от .success до .then. .then генерирует новое целое обещание, которое поставляет, когда возвращается, monitors потребителю (которое вы возвращаете в обработчике .then). С другой стороны, .success возвращает первоначальное обещание (сгенерированное $http), и данные, возвращающиеся с .success, теряются.

2) На самом деле return$http вызов (или, скорее, $http().then() вызов)

Вот концептуально, как это будет выглядеть следующим образом:

app.factory('ZMService', function ZMServiceFactory($http){ 
    return { 
     // getMonitors function of the ZMService service 
     getMonitors: function(){ 
      return $http({}) 
      .then(function(response){ 
       var data = response.data; 
       // convert data to monitors 
       return monitors; 
      }); 
     } 
    }; 
}); 

(также, заметил, как я переименовал свой сервис от ZMFactory к ZMService «Завод» в названии является неправильным. Завод является функцией, которая генерирует экземпляр - следовательно, «завод» - но сам экземпляр является объектом, который называется «услугой» в Угловом)

+0

спасибо. Мой исходный код выше имел возврат прямо над getMonitors на заводе. Разве это не эквивалентно? Также в вашем коде вы можете увидеть, есть ли {после возвращения? Я пробую ваше предложение и получаю другие проблемы, о которых я расскажу, как только я узнаю об этом разъяснении – user1361529

+0

@ user1361529, я думаю, что 'return', о котором вы говорите, является возвращаемым значением вашей заводской функции, то есть экземпляр вашего сервиса. И я проверил - похоже, я не хватает '{' - так, не уверен, что вы имеете в виду –

+0

@ user1361529, в любом случае я обновил ответ на clarfiy –

1

попробовать с этим, здесь я возвращаюсь обещание как

var app = angular.module('zmApp.controllers'); 

app.controller('zmApp.MonitorCtrl', function($ionicPlatform, $scope,$http,ZMFactory) 
{ 

      $scope.monitors=[]; 
      console.log("***CALLING FACTORY"); 
      ZMFactory.getMonitors().then(function(data) 
      { 
       $scope.monitors = data; 
       console.log ("I GOT " +$scope.monitors); 
      }); 

}); 



app.factory('ZMFactory',['$http', '$rootScope',function($http,$rootScope) 
{ 
    //var factory = {}; 
    var monitors =[]; 
    return { 
     getMonitors: function() 
     { 

      return $http({ 
        url:'http://myurl.com:9999/zm/index.php?skin=xml', 
        method:'post', 
        headers: {'Content-Type': 'application/x-www-form-urlencoded', 
           'Accept': '*/*', 
           }, 
         transformRequest: function(obj) { 
           var str = []; 
           for(var p in obj) 
           str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 
           var foo= str.join("&"); 
           console.log ("****RETURNING "+foo); 
           return foo; 
         }, 
         transformResponse: function(data) 
         { 
          var x2js = new X2JS(); 
          var json = x2js.xml_str2json(data); 
          console.log ("***Transmogrifying XML to JSON"); 
          return json; 
         }, 
         data: {username:'xxx', 
           password:'xxxx', 
           action:'login', 
           view:'console'} 

         }) //http 
         .then(function(data) 
         { 
          console.log("****YAY"+JSON.stringify(data)); 

          var subobj =data.ZM_XML.MONITOR_LIST.MONITOR; 
          var len = subobj.length; 
          for (var i =0; i< len; i++) 
          { 
          console.log ("HERE " + subobj[i].NAME); 
          monitors.push(subobj[i]); 
          } 
          // $rootScope.$broadcast ('handleZoneMinderMonitorsUpdate',monitors); 
          return monitors; 
         },function(error) 
         { 

          return error; 
         }); 

     } 
    }; 

}]); 
+0

Спасибо, пранай. Я хотел избежать $ q, так как я прочитал, что http уже дает обещание - я бы пошел по этому маршруту, если бы я не получил модель в прежнем виде, и мне удалось справиться с помощью New Dev. – user1361529

+0

еще одна вещь, я думаю, что запрос преобразования и ответ вы должны держать его в перехватчиках, чтобы очистить код –

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