我在Angular中的HTTP有一个问题。

我只是想获得一个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"
  ]
}

我认为你需要导入这个:

import 'rxjs/add/operator/map'

或者更一般地说,如果你想有更多的方法用于可观察对象。 警告:这将导入所有50+操作符并将它们添加到你的应用程序中,从而影响你的bundle大小和加载时间。

import 'rxjs/Rx';

有关详细信息,请参阅此问题。


使用可观察到的。直接订阅应该有用。

@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()); // <<--
    }
}

只是一些背景知识……新发布的服务器通信开发指南(最后)讨论/提到/解释了这一点:

The RxJS library is quite large. Size matters when we build a production application and deploy it to mobile devices. We should include only those features that we actually need. Accordingly, Angular exposes a stripped down version of Observable in the rxjs/Observable module, a version that lacks almost all operators including the ones we'd like to use here such as the map method. It's up to us to add the operators we need. We could add each operator, one-by-one, until we had a custom Observable implementation tuned precisely to our requirements.

所以正如@Thierry已经回答的那样,我们可以只引入我们需要的操作符:

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

或者,如果我们懒得,我们可以引入完整的操作符集。警告:这将添加所有50+运营商到你的应用程序包,并将影响加载时间

import 'rxjs/Rx';

因为angular2中的Http服务返回一个Observable类型, 从你的Angular2安装目录(在我的例子中是'node_modules'),我们需要使用http服务在你的组件中导入Observable的map函数,如下所示:

import 'rxjs/add/operator/map';

你在这里使用的映射不是JavaScript中的.map(),而是Rxjs的map函数,它在Angular中的可观察对象上工作。

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

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

所以像这样简单地导入它:

import 'rxjs/add/operator/map';

没错,RxJs已经在一个单独的模块中分离了它的map操作符,现在你需要像任何其他操作符一样显式导入它。

进口rxjs /添加/运营商/地图;

你会没事的。


在Angular 5中,RxJS导入得到了改进。

而不是

import 'rxjs/add/operator/map';

我们现在可以

import { map } from 'rxjs/operators';

全球进口是安全的。

进口“rxjs / Rx”;


import 'rxjs/add/operator/map';

会解决你的问题

我在angular 5.2.0和rxjs 5.5.2中测试了它


对于Angular 5及以上版本,更新后的导入行看起来是这样的:

import { map } from 'rxjs/operators';

OR

import { map } from 'rxjs/operators';

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

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

import 'rxjs/add/operator/map';

OR

import 'rxjs/add/operators/map';

如果你仍然遇到问题,那么你必须这样做:

import 'rxjs/Rx';

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


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

安装此包:

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

然后导入这个库

import 'rxjs/add/operator/map'

最后重新启动你的离子计划

ionic serve -l

从rxjs 5.5开始,你可以使用可管道操作符

import { map } from 'rxjs/operators';

导入'rxjs/add/operator/map'有什么问题;

当我们使用这个方法时,map操作符将被修补到可观察对象。原型并成为该对象的一部分。

如果稍后,你决定从处理可观察流的代码中删除map操作符,但未能删除相应的导入语句,实现map的代码仍然是observable .prototype的一部分。

当捆绑者试图消除未使用的代码(也就是摇树)时,他们可能会决定在Observable中保留map操作符的代码,即使它没有在应用程序中使用。

解决方案-可管道操作符

可管道操作符是纯函数,不会给Observable打补丁。你可以使用ES6的import语法import {map}从"rxjs/operators"导入操作符,然后将它们包装到一个函数pipe()中,该函数pipe()接受可变数量的参数,即可链操作符。

就像这样:

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

Angular 6——只有导入'rxjs/Rx'才管用


只要在你的文件里加上这行,

import 'rxjs/Rx';

它会导入一堆依赖项。在angular 5中测试


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

但是如果你正在使用rxjs-compat,那么你只需要导入rxjs-compat操作符


Angular版本6 "0.6.8" RXJS版本6 "^6.0.0"

此解决方案适用于:

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

我们都知道angular每天都在开发,所以每天都有很多变化,这个解决方案是针对angular 6和RXJS 6的 首先要使用HTTP,你应该导入它从: 毕竟你必须在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函数:

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()  )  );
    }

那太好了祝你好运!


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

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


import 'rxjs/Rx';

Import {map} from 'rxjs/operators';

这适用于我的angular 8


加上@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