TypeScript继承类报错:Cannot read property 'get' of undefined 求助
解决TypeScript错误:Cannot read property 'get' of undefined
问题根源
这个错误的核心原因很明确:你在实例化App类时使用了new App(),没有传入Http实例,导致父类Base中的this.http为undefined,调用this.http.get()时自然就抛出了这个错误。另外你的Base类还缺少Observable相关的导入,这也是一个潜在的编译问题。
分步解决方案
1. 先修复base.ts的导入问题
首先补上Observable和RxJS操作符的导入,否则代码会先出现编译错误:
// base.ts import { Http, Response } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; export class Base { constructor(public http?: Http) {} getJSON(url): Observable<any> { return this.http.get(url) .map((res: Response) => res.json()) .catch((error: any) => Observable.throw(error.json())) } }
2. 正确注入Http服务(推荐遵循Angular规范)
在Angular中,Http是框架提供的服务,不能直接手动new实例,应该通过**依赖注入(DI)**来获取,这是Angular的核心设计理念。
第一步:把App类声明为可注入服务
// app.ts import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { Base } from './base'; @Injectable() export class App extends Base { // 这里可以去掉?,因为DI会确保传入合法的Http实例 constructor(public http: Http) { super(http); } run() { this.getJSON('./test-data.json') .subscribe( data => console.log('请求成功:', data), error => console.error('请求失败:', error) ); } }
第二步:在模块中注册必要的依赖
在你的根模块(比如AppModule)中导入HttpModule并注册App服务:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpModule } from '@angular/http'; import { App } from './app'; @NgModule({ imports: [BrowserModule, HttpModule], providers: [App] }) export class AppModule {}
第三步:通过DI获取App实例
修改test.ts,让Angular注入App实例,而不是手动new:
// test.ts import { App } from './app'; class Test { constructor(private app: App) { this.app.run(); } }
3. 如果必须手动实例化(不推荐)
如果你因为特殊需求一定要手动创建App实例,需要手动构建Http的依赖链(这很繁琐,且不符合Angular设计):
// test.ts import { Http, XHRBackend, RequestOptions } from '@angular/http'; import { App } from './app'; class Test { constructor() { // 手动创建Http所需的依赖实例 const http = new Http(new XHRBackend(new RequestOptions()), new RequestOptions()); const page = new App(http); page.run(); } }
额外建议:升级到HttpClient
如果你的Angular版本是4.3及以上,强烈建议使用HttpClient替代旧的Http服务——它已经被废弃,且HttpClient自带JSON解析,代码更简洁:
// base.ts(使用HttpClient版本) import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; export class Base { constructor(public http?: HttpClient) {} getJSON(url): Observable<any> { return this.http.get(url) .pipe( catchError((error: HttpErrorResponse) => throwError(error.error)) ); } }
对应的模块要导入HttpClientModule,其他代码逻辑类似。
内容的提问来源于stack exchange,提问作者jawahar
相关产品推荐
相关产品推荐

