2014-04-03 2 views
3

Я изменил HTTP> параметр URL $ внутри моего AngularJS приложение отAngularJS TypeError: Не удается прочитать 'протокол' свойство неопределенной

 $http({ method:'POST', 
        url:'http://localhost/api/clients.php' 
     }).success(function(data,status,headers,config){ 
        deferred.resolve(data); 
     }).error(function(data,status,headers,config){ 
        deferred.reject(status); 
     }); 

в

 $http({ method:'POST', 
        url: ConfigService.Urls.Clients 
     }).success(function(data,status,headers,config){ 
        deferred.resolve(data); 
     }).error(function(data,status,headers,config){ 
        deferred.reject(status); 
     }); 

где ConfigService выглядит следующим образом:

Urls: {}, 
loadUrls: function(){ 
    Urls.Clients = 'http://localhost/api/clients.php'; 
} 

Конечно, я вызываю loadUrls перед загрузкой контроллера через .Resolve, поэтому я на 100% уверен, что Urls.Clients i s не равно нулю.

После того как я сделал это изменение, которое я начал получать сообщение об ошибке:

TypeError: Cannot read property 'protocol' of undefined 
    at urlIsSameOrigin (http://localhost/myapp/app/lib/angular/angular.js:13710:17) 
    at $http (http://localhost/myapp/app/lib/angular/angular.js:7508:23) 

Что настолько запутанное, что приложение работает просто отлично, за эту ошибку я получаю за исключением ... может кто-то пожалуйста, скажи мне, что я я здесь делаю неправильно? и почему я получаю эту ошибку, если приложение уже работает без проблем.

+0

Поможет ли это вообще: http://stackoverflow.com/questions/21347542/can not-read-property-protocol-of-undefined –

+0

@drew_w Нет, поскольку это другой случай, здесь я не разделяю заголовок – MChan

+0

Можете ли вы добавить полный вызов $ http? –

ответ

2

Это явно проблема с заказом. loadUrls не получает вызов до тех пор, пока вызов $http не будет запущен в первый раз. Это может быть связано с тем, что контроллеры не обязательно загружаются в ожидаемом порядке - вы не можете рассчитывать на открытие провайдера маршрута и запуск вашего домашнего контроллера, прежде чем он запускает другие контроллеры, - это зависит только от того, как настроены настройки. Учитывая объем кода, который вы здесь указали, трудно сказать, что именно происходит с порядком.

Это в виду, у вас есть несколько общих параметров, которые будут исправить это:

  • Всегда вызывайте loadUrls() перед запуском $http запрос. Это не изящно, но это исправит проблему.
  • Оберните все ваши звонки $http и позвоните loadUrls() в этой обертке. Это немного лучше предыдущего, потому что если вам нужно изменить loadUrls() или убедиться, что он вызывается только один раз, когда вы сможете реализовать эту логику позже.
  • Вы уже это заметили, но вы можете изменить свою инициализацию непосредственно на службу, а не на рутину, предоставляемую службой. Это устранит проблему, хотя она может оставить вас в месте, где вам необходимо обновлять службу каждый раз при изменении URL.
  • Живите с ошибкой, зная, что при загрузке контроллера он будет создавать экземпляр и получать правильные данные в этот момент времени. Мне часто не нравятся такие решения, потому что это может привести к ошибкам, которые трудно проследить, но если вам не нравятся какие-либо из предыдущих вариантов, это может быть технически в порядке.
  • Используйте конфигурацию приложения, которая выполняется при загрузке приложения (обратите внимание, что не все ресурсы инициализированы, а вставка не разрешена). Пример from the documentation:

    angular.module('myModule', []). 
        config(function(injectables) { 
         // provider-injector 
         // This is an example of config block. 
         // You can have as many of these as you want. 
         // You can only inject Providers (not instances) 
         // into config blocks. 
        }). 
    

    Вы можете использовать это или запустить блок инициализации, что вы хотите

Я уверен, что есть и другие варианты, а также в зависимости от того, как структурирован ваш код, но мы надеемся, это, по крайней мере, заставляет вас начать. Удачи!

+0

Вы правы, происходит то, что вызов $ http возвращает обещание, но код, вызывающий ошибку, выполняется до того, как обещание выполнено. Есть ли способ, который я могу вызвать $ http при запуске приложения и предотвратить запуск приложения, если обещание не удастся? – MChan

+0

@MChan Я добавил еще один вариант, который, вероятно, сделает то, что вы ищете здесь. Поскольку инициализация самого углового вы ничего не можете сделать, но 'run' или' config', вероятно, должны вас продвигать дальше. –

+0

Я не могу вводить свою службу в конфигурацию, поэтому она не сильно поможет – MChan

-1

У меня была такая же проблема, и я установил ее, изменив следующим образом:

var logoutURL = URL + '/logout'; 
    function sendLogoutHttp(){ 
     return $http({ 
      method: 'GET', 
      url: logoutURL, 
      headers: {'Content-Type': 'application/x-www-form-urlencoded'} 
     }); 
    } 

к этому

function sendLogoutHttp(){ 
     var logoutURL = URL + '/logout'; 
     return $http({ 
      method: 'GET', 
      url: logoutURL, 
      headers: {'Content-Type': 'application/x-www-form-urlencoded'} 
     }); 
    } 
Смежные вопросы