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

时间:2015-12-29 16:35:49

标签: angular rxjs

我在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]

中的函数

霍尔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"
  ]
}

19 个答案:

答案 0 :(得分:524)

我认为您需要导入此内容:

import 'rxjs/add/operator/map'

或者更常见的是,如果你想有更多的观察方法。 警告:这将导入所有50多个操作员并将其添加到您的应用程序中,从而影响您的捆绑包大小和加载时间。

import 'rxjs/Rx';

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

答案 1 :(得分:81)

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

  

RxJS库非常庞大。在构建生产应用程序并将其部署到移动设备时,大小很重要。我们应该只包括我们真正需要的那些功能。

     

因此,Angular在Observable模块中公开了rxjs/Observable的精简版本,这个版本缺少几乎所有运算符,包括我们想在这里使用的运算符,例如{{1}方法。

     

由我们来添加我们需要的运算符。我们可以逐个添加每个运算符,直到我们根据我们的要求调整自定义Observable实现。

正如@Thierry已经回答的那样,我们可以拉入我们需要的运营商:

map

或者,如果我们懒惰,我们可以拉入全套操作员。 警告:这会将所有50多个运营商添加到您的应用包中,并会影响加载时间

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

答案 2 :(得分:15)

使用Angular 5,RxJS导入得到改善。

而不是

import 'rxjs/add/operator/map';

我们现在可以

import { map } from 'rxjs/operators';

答案 3 :(得分:13)

直接使用pre-process应该有效。

Observable.subscribe

答案 4 :(得分:13)

rxjs 5.5 开始,您可以使用 pipeable 运算符

. myscript.sh

sh myscipt.sh

有什么问题?

使用这种方法时,import { map } from 'rxjs/operators'; 运算符将被修补到import 'rxjs/add/operator/map';并成为该对象的一部分。

如果稍后您决定从处理可观察流的代码中删除map运算符,但无法删除相应的import语句,则实现observable.prototype的代码仍是{{ 1}}。

当捆绑程序尝试消除未使用的代码( aka map)时,他们可能决定将map运算符的代码保留在Observable中,即使不是在应用程序中使用。

解决方案-Observable.prototype

Pipeable 运算符是纯函数,不修补 Observable 。您可以使用ES6导入语法tree shaking导入运算符,然后将它们包装到具有可变数量参数的函数map中,即可链接运算符。

类似这样的东西:

Pipeable operators

答案 5 :(得分:3)

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

import { map } from 'rxjs/operators';

OR

import { map } from 'rxjs/operators';

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

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

import 'rxjs/add/operator/map';

OR

import 'rxjs/add/operators/map';

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

import 'rxjs/Rx';

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

答案 6 :(得分:3)

角度版本6“ 0.6.8” rxjs版本6“ ^ 6.0.0”

此解决方案适用于:

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

我们都知道Angle每天都在开发,所以每天都有很多变化,并且此解决方案适用于angular 6和rxjs 6
首先使用http yo的应从中导入:  毕竟,您必须在app.module.ts中声明HttpModule

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

,您必须将HttpModule添加到Ngmodule-> 导入

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

第二次使用地图,您应该首先导入管道:

import { pipe } from 'rxjs';

您需要从以下位置导入地图函数:

import { map } from 'rxjs/operators';

您必须在管道内部使用地图,例如:

 constructor(public http:Http){  }

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

祝你好运!

答案 7 :(得分:3)

我有解决此问题的方法

安装此软件包:

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

然后导入该库

import 'rxjs/add/operator/map'

最后重新启动您的离子项目,然后

ionic serve -l

答案 8 :(得分:2)

你在这里使用的地图不是javascript中的.map(),它是在Angular中处理Observables的Rxjs地图函数...

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

  

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

所以只需像这样导入它:

import 'rxjs/add/operator/map';

答案 9 :(得分:1)

全球导入是安全的。

导入&#39; rxjs / Rx&#39;;

答案 10 :(得分:1)

Angular 6-仅导入'rxjs / Rx'对我有用了

答案 11 :(得分:1)

只需将行添加到文件中,

导入'rxjs / Rx';

它将导入一堆依赖项。在角度5中进行了测试

答案 12 :(得分:1)

由于 angular2 中的 Http 服务会返回可观察类型, 从Angular2安装目录(在我的例子中是'node_modules'),我们需要使用 http 服务在组件中导入Observable的地图功能,如下所示:

import 'rxjs/add/operator/map';

答案 13 :(得分:0)

import 'rxjs/add/operator/map';

将解决您的问题

我在角度5.2.0和rxjs 5.5.2

中进行了测试

答案 14 :(得分:0)

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

import rxjs/add/operator/map;

你会没事的。

答案 15 :(得分:0)

之所以发生这种情况,是因为您使用的是rxjs,并且rxjs函数不是静态的,这意味着您不能直接调用它们,必须调用管道内的方法并从rxjs库中导入该函数

但是,如果您使用的是rxjs-compat运算符,则只需导入rxjs-compat运算符

答案 16 :(得分:0)

我尝试了以下命令,它得到了修复:

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


import 'rxjs/Rx';

答案 17 :(得分:0)

从'rxjs / operators'导入{map};

这对我来说适用于8号角

答案 18 :(得分:0)

加上@ mlc-mlapis的评论,您正在混合可操作的运算符和原型修补方法。使用一个或另一个

您的情况应该是

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';

@Injectable()
export class SwPeopleService {
    people$ = this.http.get('https://swapi.co/api/people/')
      .map((res:any) => res.results);

    constructor(private http: HttpClient) {} 
}

https://stackblitz.com/edit/angular-http-observables-9nchvz?file=app%2Fsw-people.service.ts