AngularJS服务用$http和$cookies报错:Cannot read property 'then' of undefined
嘿,我仔细看了你的代码和错误栈,这个问题100%是依赖注入顺序不匹配导致的——这在AngularJS使用静态$inject数组时非常容易踩坑!
核心问题:$inject数组与构造函数参数顺序完全不匹配
你定义的静态注入数组是:
static $inject = ['$rootScope','$http', '$cookies', '$q','$cookieStore','$window'];
但构造函数的参数顺序却是:
constructor(public $scope: ng.IScope, public $window: ng.IWindowService, public $http: ng.IHttpService, private $q: ng.IQService, public $cookieStore: ng.cookies.ICookieStoreService, public $cookies: ng.cookies.ICookiesService) { }
这里有两个致命问题:
$inject里写的是$rootScope,但构造函数里用的是$scope,完全对应不上- 整体顺序彻底混乱:AngularJS会严格按照
$inject的顺序把服务注入到构造函数的参数里,这就导致你以为的$http其实被注入了$window,而真正的$http根本没被正确注入,最后调用this.$http.get()时,这个$http要么是undefined,要么是一个非promise对象,自然没有then方法,就抛出了那个错误。
快速修复方案
把$inject数组的顺序严格对应构造函数的参数顺序,同时修正$rootScope为$scope:
static $inject = ['$scope','$window','$http','$q','$cookieStore','$cookies'];
这样AngularJS就能把正确的服务注入到对应的参数里,$http会被正确初始化,调用get()后返回的promise自然就有then方法了。
额外的优化建议
- 确保模块已引入ngCookies:在你的AngularJS模块定义里,一定要把
ngCookies作为依赖项,比如:
angular.module('yourAppName', ['ngCookies']);
这是使用$cookies和$cookieStore的前提。
- 避免Deferred反模式:你的
loginUserOnApi方法手动创建了deferred,但其实$http本身就返回一个promise,完全没必要多此一举,简化后的代码更简洁且不容易出错:
loginUserOnApi (userData: any) { const parameters = { username: userData.title, password: userData.password }; const config = { params: parameters, withCredentials: true, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }; return this.$http.get(this.loginApiUrl, config) .then(response => { this.status = response.data['ack']; this.$cookies.putObject('new-acc-var', response); return response.data; // 直接返回数据,调用方可以用then接收 }); }
验证修复
修正完注入顺序和模块依赖后,重新运行代码,你会发现$http能正常发起请求并返回promise,then方法也能正常调用,那个错误就会消失了。
内容的提问来源于stack exchange,提问作者Huzur Polat
相关产品推荐
相关产品推荐

