首页 文章

带有TypeScript错误的Angular HTTP GET http.get(...) . map不是[null]中的函数

提问于
浏览
289

我在Angular中遇到HTTP问题 .

我只想 GET JSON 列表并在视图中显示它 .

服务类

import {Injectable} from "angular2/core";
import {Hall} from "./hall";
import {Http} from "angular2/http";
@Injectable()
export class HallService {
    public http:Http;
    public static PATH:string = 'app/backend/'    

    constructor(http:Http) {
        this.http=http;
    }

    getHalls() {
           return this.http.get(HallService.PATH + 'hall.json').map((res:Response) => res.json());
    }
}

HallListComponent 中,我从服务中调用 getHalls 方法:

export class HallListComponent implements OnInit {
    public halls:Hall[];
    public _selectedId:number;

    constructor(private _router:Router,
                private _routeParams:RouteParams,
                private _service:HallService) {
        this._selectedId = +_routeParams.get('id');
    }

    ngOnInit() {
        this._service.getHalls().subscribe((halls:Hall[])=>{ 
            this.halls=halls;
        });
    }
}

但是,我有一个例外:

TypeError:this.http.get(...) . map不是[null]中的函数

hall-center.component

import {Component} from "angular2/core";
import {RouterOutlet} from "angular2/router";
import {HallService} from "./hall.service";
import {RouteConfig} from "angular2/router";
import {HallListComponent} from "./hall-list.component";
import {HallDetailComponent} from "./hall-detail.component";
@Component({
    template:`
        <h2>my app</h2>
        <router-outlet></router-outlet>
    `,
    directives: [RouterOutlet],
    providers: [HallService]
})

@RouteConfig([
    {path: '/',         name: 'HallCenter', component:HallListComponent, useAsDefault:true},
    {path: '/hall-list', name: 'HallList', component:HallListComponent}
])

export class HallCenterComponent{}

app.component

import {Component} from 'angular2/core';
import {ROUTER_DIRECTIVES} from "angular2/router";
import {RouteConfig} from "angular2/router";
import {HallCenterComponent} from "./hall/hall-center.component";
@Component({
    selector: 'my-app',
    template: `
        <h1>Examenopdracht Factory</h1>
        <a [routerLink]="['HallCenter']">Hall overview</a>
        <router-outlet></router-outlet>
    `,
    directives: [ROUTER_DIRECTIVES]
})

@RouteConfig([
    {path: '/hall-center/...', name:'HallCenter',component:HallCenterComponent,useAsDefault:true}
])
export class AppComponent { }

tsconfig.json

{
  "compilerOptions": {
    "target": "ES5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules"
  ]
}

16 回答

  • 507

    我认为你需要导入这个:

    import 'rxjs/add/operator/map'
    

    或者更常见的是,如果您想要有更多可观察方法 . WARNING: This will import all 50+ operators and add them to your application, thus affecting your bundle size and load times.

    import 'rxjs/Rx';
    

    有关详细信息,请参阅this issue .

  • 77

    全球进口是安全的 .

    import'rxjs / Rx';

  • 10

    我有一个解决这个问题的方法

    安装此包:

    npm install rxjs@6 rxjs-compat@6 --save
    

    然后导入这个库

    import 'rxjs/add/operator/map'
    

    最后重启你的离子项目

    ionic serve -l
    
  • 8

    从rxjs 5.5开始,您可以使用可管道运算符

    import { map } from 'rxjs/operators';
    

    What is wrong with the import 'rxjs/add/operator/map';

    当我们使用这种方法时, map 运算符将被修补为 observable.prototype 并成为此对象的一部分 .

    如果稍后,您决定从处理可观察流的代码中删除 map 运算符但未能删除相应的import语句,则实现 map 的代码仍然是 Observable.prototype 的一部分 .

    当捆绑器试图消除未使用的代码(a.k.a . tree shaking )时,即使它没有在应用程序中使用,它们也可能决定将 map 运算符的代码保留在Observable中 .

    Solution - Pipeable operators

    可管理运算符是纯函数,不修补Observable . 您可以使用ES6导入语法 import { map } from "rxjs/operators" 导入运算符,然后将它们包装到一个函数 pipe() 中,该函数采用可变数量的参数,即可链式运算符 .

    像这样的东西:

    getHalls() {
        return this.http.get(HallService.PATH + 'hall.json')
        .pipe(
            map((res: Response) => res.json())
        );
    }
    
  • 0

    这是因为你正在使用rxjs并且在rxjs函数中不是静态的,这意味着你不能直接调用它们你必须调用管道内的方法并从rxjs库中导入该函数

    但是如果你使用的是rxjs-compat,那么你只需要导入rxjs-compat运算符

  • 1

    对于Angular版本5及更高版本,更新的导入行如下所示:

    import { map } from 'rxjs/operators';
    

    要么

    import { map } from 'rxjs/operators';
    

    这些版本也完全支持Pipable Operators,因此您可以轻松使用.pipe()和.subscribe() .

    如果您使用的是Angular版本2,那么以下行应该可以正常工作:

    import 'rxjs/add/operator/map';
    

    要么

    import 'rxjs/add/operators/map';
    

    如果您仍然遇到问题,那么您必须使用:

    import 'rxjs/Rx';
    

    我不希望你直接使用它bcoz它会增加加载时间,因为它有大量的操作符(有用和无用的)根据行业规范不是一个好的做法,所以确保你首先尝试使用上面提到的导入行,如果这不起作用那么你应该去rxjs / Rx

  • 14

    由于 angular2 中的 Http 服务返回 Observable 类型,从您的Angular2安装目录(在我的情况下为'node_modules'),我们需要使用 http 服务在 component 中导入Observable的 Map 功能,如下所示:

    import 'rxjs/add/operator/map';
    
  • 0

    Angular 6 - 只导入'rxjs / Rx'为我做了诀窍

  • 1

    Angular版本6“0.6.8”rxjs版本6“^ 6.0.0”

    此解决方案适用于:

    "@angular-devkit/core": "0.6.8",
      "rxjs": "^6.0.0"
    

    因为我们都知道角度每天都在发展,所以每天都有很多变化,这个解决方案适用于角度6和rxjs 6
    首先使用http yo应该从以下位置导入:毕竟你必须在app.module.ts中声明HttpModule

    import { Http } from '@angular/http';
    

    你必须将HttpModule添加到Ngmodule - > imports

    imports: [
        HttpModule,
        BrowserModule,
        FormsModule,
        RouterModule.forRoot(appRoutes)
      ],
    

    第二个使用map你应该先导入管道:

    import { pipe } from 'rxjs';
    

    第三,你需要从以下 Map 导入 Map 功能:

    import { map } from 'rxjs/operators';
    

    你必须像这样的例子使用管道内的 Map :

    constructor(public http:Http){  }
    
        getusersGET(){
            return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
             map(res => res.json()  )  );
        }
    

    这非常好运!

  • 0

    只需在您的文件中添加该行,

    import'rxjs / Rx';

    它将导入一堆依赖项 . 测试角度为5

  • 1

    你在这里使用的 map 不是javascript中的 .map() ,它是在Angular中 Observables 上工作的Rxjs map函数...

    所以在这种情况下,如果你想在结果数据上使用map,你需要导入它...

    map(project:function(value:T,index:number):R,thisArg:any):Observable <R>将给定的项目函数应用于源Observable发出的每个值,并将结果值作为Observable发出 .

    所以只需像这样导入它:

    import 'rxjs/add/operator/map';
    
  • 3
    import 'rxjs/add/operator/map';
    

    将解决您的问题

    我在角度5.2.0和rxjs 5.5.2中测试了它

  • 0

    使用Angular 5,RxJS导入得到了改进 .

    代替

    import 'rxjs/add/operator/map';
    

    我们现在可以

    import { map } from 'rxjs/operators';
    
  • 2

    没错,RxJs已将其 Map 运算符分离到一个单独的模块中,现在您需要像其他任何运算符一样明确地导入它 .

    import rxjs/add/operator/map;

    你会没事的

  • 3

    直接使用 Observable.subscribe 应该可行 .

    @Injectable()
    export class HallService {
        public http:Http;
        public static PATH:string = 'app/backend/'    
    
        constructor(http:Http) {
            this.http=http;
        }
    
        getHalls() {
        // ########### No map
               return this.http.get(HallService.PATH + 'hall.json');
        }
    }
    
    
    export class HallListComponent implements OnInit {
        public halls:Hall[];
        / *** /
        ngOnInit() {
            this._service.getHalls()
               .subscribe(halls => this.halls = halls.json()); // <<--
        }
    }
    
  • 0

    只是一些背景......新铸造的Server Communication开发指南(最后)讨论/提及/解释这个:

    RxJS库非常大 . 在构建 生产环境 应用程序并将其部署到移动设备时,大小很重要 . 我们应该只包括我们实际需要的那些功能 . 因此,Angular在rxjs / Observable模块中公开了一个精简的Observable版本,这个版本缺少几乎所有的运算符,包括我们想在这里使用的运算符,例如map方法 . 由我们来添加我们需要的运算符 . 我们可以逐个添加每个运算符,直到我们有一个自定义的Observable实现,精确地根据我们的要求进行调整 .

    因此,@ Thierry已经回答,我们可以引入我们需要的运营商:

    import 'rxjs/add/operator/map';
    import 'rxjs/operator/delay';
    import 'rxjs/operator/mergeMap';
    import 'rxjs/operator/switchMap';
    

    或者,如果我们懒惰,我们可以拉入全套操作员 . WARNING: this will add all 50+ operators to your app bundle, and will effect load times

    import 'rxjs/Rx';
    

相关问题