从 Angular 2 升级到 Angular 4 后,无法读取 Observable 未定义的 属性 'of'
Cannot read property 'of' of undefined for Observable after upgrading from Angular 2 to Angular 4
在我将 Angular 2 和 RxJs 升级到最新版本之前,Following Service 及其 Observable 一直运行良好。
尝试执行以下命令时出现错误“无法读取未定义的属性'of'”代码行:
if (this.loggedContact) {
return Observable.of(this.loggedContact);
}
我看到 this.loggedContact 已经有价值了。看起来它认为 Observable 是未定义的。有什么东西改变了我们过去 return 将对象作为 Observable 的方式吗?
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"angular2-busy": "2.0.4",
"bootstrap": "3.3.7",
"core-js": "2.5.1",
"jquery": "3.2.1",
"ng2-completer": "^1.3.1",
"ng2-toasty": "^4.0.3",
"reflect-metadata": "0.1.10",
"rxjs": "^5.4.3",
"systemjs": "^0.20.18",
"zone.js": "^0.8.17"
服务内容如下:
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
loggedContact: CostarContactVM;
observable: Observable<any>;
getLoggedContact(): Observable<Contact> {
if (this.loggedContact) {
return Observable.of(this.loggedContact);
}
else if (this.observable)
return this.observable;
else {
this.observable = this.http.get(this.contactUrl)
.map(res => {
this.observable = null;
if (res.status == 400) {
return "FAILURE";
}
else if (res.status === 200) {
this.loggedContact = res.json() as Contact;
return this.loggedContact;
}
})
.share();
return this.observable;
}
}
以下是 System.Config 同样的:
(function (global) {
System.config({
meta: {
'*': { authorization: true }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
map: {
app: 'app',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'rxjs': 'npm:rxjs'
},
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
我通过升级到 Angular 4.0 找到了问题的解决方案。基本上,我将我的 RxJs 从 5.0.1 升级到 5.4.3,它现在支持来自 @angular/common/http 位置的 HttpClient 模块,而不是来自 @angular/http.
的 Http
我将所有引用升级到 HttpClient 并更新了我的代码,如下所示,它解决了问题。我希望它能帮助别人。
重点是升级到Angular 4,记得把你的http升级到httpClient。
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';
@Injectable()
export class ContactService {
loggedContact: CostarContactVM;
getLoggedContact(): Observable<ContactVM> {
return this.httpClient.get<ContactVM>(this.contactUrl)
.catch(this.handleError)
.do((data) => {
this.assignPermissions(data);
});
}
在我将 Angular 2 和 RxJs 升级到最新版本之前,Following Service 及其 Observable 一直运行良好。
尝试执行以下命令时出现错误“无法读取未定义的属性'of'”代码行:
if (this.loggedContact) {
return Observable.of(this.loggedContact);
}
我看到 this.loggedContact 已经有价值了。看起来它认为 Observable 是未定义的。有什么东西改变了我们过去 return 将对象作为 Observable 的方式吗?
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"angular2-busy": "2.0.4",
"bootstrap": "3.3.7",
"core-js": "2.5.1",
"jquery": "3.2.1",
"ng2-completer": "^1.3.1",
"ng2-toasty": "^4.0.3",
"reflect-metadata": "0.1.10",
"rxjs": "^5.4.3",
"systemjs": "^0.20.18",
"zone.js": "^0.8.17"
服务内容如下:
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
loggedContact: CostarContactVM;
observable: Observable<any>;
getLoggedContact(): Observable<Contact> {
if (this.loggedContact) {
return Observable.of(this.loggedContact);
}
else if (this.observable)
return this.observable;
else {
this.observable = this.http.get(this.contactUrl)
.map(res => {
this.observable = null;
if (res.status == 400) {
return "FAILURE";
}
else if (res.status === 200) {
this.loggedContact = res.json() as Contact;
return this.loggedContact;
}
})
.share();
return this.observable;
}
}
以下是 System.Config 同样的:
(function (global) {
System.config({
meta: {
'*': { authorization: true }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
map: {
app: 'app',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'rxjs': 'npm:rxjs'
},
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
我通过升级到 Angular 4.0 找到了问题的解决方案。基本上,我将我的 RxJs 从 5.0.1 升级到 5.4.3,它现在支持来自 @angular/common/http 位置的 HttpClient 模块,而不是来自 @angular/http.
的 Http我将所有引用升级到 HttpClient 并更新了我的代码,如下所示,它解决了问题。我希望它能帮助别人。 重点是升级到Angular 4,记得把你的http升级到httpClient。
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';
@Injectable()
export class ContactService {
loggedContact: CostarContactVM;
getLoggedContact(): Observable<ContactVM> {
return this.httpClient.get<ContactVM>(this.contactUrl)
.catch(this.handleError)
.do((data) => {
this.assignPermissions(data);
});
}