TypeScript 오류 http.get (…) .map이있는 각도 HTTP GET은 [null]의 함수가 아닙니다.


334

Angular의 HTTP에 문제가 있습니다.

난 그냥 원하는 목록보기에 표시됩니다.GETJSON

서비스 클래스

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]의 함수가 아닙니다.

홀 중심 구성 요소

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

http.get이 약속을 반환하지 않습니까?
bmm6o

1
@ bmm6o 새로운 Http서비스는 Observable을 반환합니다
Brocco

1
Angular2 베타 17에서 최종 릴리스로 프로젝트를 마이그레이션하려고 시도하면서 거의 동일한 문제가 발생했습니다. VS 2015, Update 3을 사용하는 문제는 IDE였습니다. 유형 스크립트 언어 서비스 확장은 여전히 1.8.36있었지만 ng2 빠른 시작 안내서 (이 글을 쓸 때)는을 사용 "typescript": "^2.0.2"합니다. TS 언어 업그레이드 확장 기능 및 업데이트를 통한 서비스가 나를 위해 속였습니다. 그 업데이트가 설치되는 동안 나는 이 SO answer를 발견했습니다 . 이는 같은 결론으로 ​​끝납니다.
Eric Lease

phpstorm / webstorm의 경우 내 프로젝트 라이브러리로 typescript 버전을 업데이트하면 문제가 해결되었습니다. 나는이 SO 답변의 단계를 따랐다 : stackoverflow.com/a/31608934/1291428
Sebas

답변:


538

이것을 가져와야한다고 생각합니다.

import 'rxjs/add/operator/map'

또는 더 일반적으로 관찰 가능 항목에 대한 더 많은 방법을 원한다면 경고 : 50 개 이상의 연산자를 모두 가져 와서 응용 프로그램에 추가하여 번들 크기 및로드 시간에 영향을줍니다.

import 'rxjs/Rx';

자세한 내용은 이 문제 를 참조하십시오.


1
여전히 어떤 오류가 남아 있습니까? stackoverflow에서 이것에 관한 몇 가지 구체적인 질문을 할 수 있습니다 ;-)이 질문은 아마도 당신을 도울 것입니다 : stackoverflow.com/questions/34450131/… .
Thierry Templier

1
Angular 2 RC 0부터는 더 이상 필요하지 않습니다.
Onur Yıldırım

3
@ OnurYıldırım, rc.4를 사용하면 내가 잘못하고 있지 않는 한이 가져 오기가 여전히 필요합니다.
Joseph Gabriel

18
'import'rxjs / Rx ';'를 사용하지 마십시오 모든 것을 가져오고 rxjs는 꽤 큰 경향이 있기 때문입니다. 필요에 따라 연산자를 하나씩 가져옵니다.
Drag0

1
rxjs가있는 Angular 2 : 5.0.0-beta.12. 그리고 난 여전히 import 'rxjs/add/operator/do'... 우리가 .map()더 이상 이 작업을 수행 할 필요는 없습니다. 그러나 이것은 필자 .do()가 가져와야 할 필요가 있음을 깨닫는 데 도움이되었습니다 . 감사합니다! 나에게서 하나의 투표 :)
MrCroft

82

약간의 배경 지식 ... 새로 제작 된 서버 커뮤니케이션 개발 가이드 (최종)가 이에 대해 논의 / 멘션 / 설명합니다.

RxJS 라이브러리는 상당히 큽니다. 프로덕션 응용 프로그램을 빌드하고 모바일 장치에 배포 할 때 크기가 중요합니다. 실제로 필요한 기능 만 포함해야합니다.

따라서 Angular는 모듈 Observable에서 제거 된 버전을 노출합니다 rxjs/Observable.이 버전은 map메소드 와 같이 여기에서 사용하려는 연산자를 포함하여 거의 모든 연산자가 부족합니다 .

필요한 연산자를 추가하는 것은 우리의 책임입니다. 요구 사항에 맞게 사용자 지정 Observable 구현을 조정할 때까지 각 연산자를 하나씩 추가 할 수 있습니다.

@Thierry가 이미 대답했듯이 필요한 연산자를 가져올 수 있습니다.

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

또는 게으른 경우 전체 연산자 집합을 가져올 수 있습니다. 경고 : 이렇게하면 50 개 이상의 연산자가 모두 앱 번들에 추가되고로드 시간에 영향을 미칩니다

import 'rxjs/Rx';

2
수입 'rxjs / Rx'; 와. 머리를 당기면 즉시 사라집니다. 나는 이것이 Rxjs / Angular2에 대해 전 세계적으로 인쇄되지 않는다고 믿을 수 없다. 감사!!!
JimB

그러나 자주 보풀이 생기지 않으며 기본적으로 블랙리스트 수입품입니다. 새로운 앵귤러 CLI 프로젝트를 작성하십시오. 나는 편의상 자신을 좋아하지만 NYC에서 일하는 곳의 컨벤션은 그것을하지 않는 것입니다.
Tim Consolazio

21

에서 5.5 rxjs 이후, 당신은 사용할 수 있습니다 pipeable 연산자

import { map } from 'rxjs/operators';

무엇이 잘못 되었습니까? import 'rxjs/add/operator/map';

이 접근법을 사용하면 map연산자가 패치되어이 observable.prototype 객체의 일부가됩니다.

나중에 map관찰 가능 스트림을 처리하는 코드에서 연산자 를 제거 하려고하지만 해당 import 문을 제거하지 못하는 경우 구현하는 코드 map는의 일부로 유지 Observable.prototype됩니다.

번 들러는 사용하지 않는 코드 ( 일명 tree shaking ) 를 제거하려고 할 때 map애플리케이션에서 사용되지 않더라도 연산자 코드를 Observable 에 유지하기로 결정할 수 있습니다 .

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

16

Angular 5에서는 RxJS 가져 오기가 개선되었습니다.

대신에

import 'rxjs/add/operator/map';

우리는 지금 할 수 있습니다

import { map } from 'rxjs/operators';

이 접근법을 사용하면 현재 빌드에서 사용 된 연산자 (이 경우 맵) 만 포함되며 이전에는 rxjs 라이브러리의 모든 연산자를 포함했습니다. 자세한 내용은 아래 링크를 확인하십시오. loiane.com/2017/08/angular-rxjs-imports
Hiren Shah

13

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

5
이것은 매우 효율적인 접근 방식이 아닙니다. 예를 들어 가입자가 여러 명인 경우 서비스에서 한 번만 수행하는 대신 데이터에서 각각 맵을 실행해야합니다. OP가 올바른 접근 방식을 가지고 있다고 생각합니다. 사용하기에 적합한 모듈이로드되지 않았습니다.
Evan Plaice

3

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로 이동하십시오.


3

이 문제에 대한 해결책이 있습니다

이 패키지를 설치하십시오 :

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

그런 다음이 라이브러리를 가져옵니다

import 'rxjs/add/operator/map'

마지막으로 이온 프로젝트를 다시 시작하십시오.

ionic serve -l

3

각도 버전 6 "0.6.8"rxjs 버전 6 "^ 6.0.0"

이 솔루션은

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

우리는 모두 각도가 매일 개발되고 있음을 알고 있으므로 매일 많은 변화가 있으며이 솔루션은 각도 6과 rxjs 6이
먼저 http와 작동하도록해야합니다. module.ts

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

Ngmodule에 HttpModule을 추가해야합니다-> 가져 오기

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

그 행운을 완벽하게 작동합니다!


2

여기서 사용 하는 .map() 은 자바 스크립트 가 아니며 ObservablesAngular에서 작동하는 Rxjs 맵 함수입니다 ...

이 경우 결과 데이터에 map을 사용하려면 가져와야합니다.

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> 소스 Observable에서 방출 된 각 값에 지정된 프로젝트 기능을 적용하고 결과 값을 Observable로 방출합니다.

따라서 간단히 다음과 같이 가져 오십시오.

import 'rxjs/add/operator/map';

1

이후 의 HTTP 에서 서비스 angular2 다시 표시 관찰 가능한 유형, 당신의 Angular2 설치 디렉토리에서 (내 경우에는 'node_modules')는, 우리는 당신의 관측의 수입 맵 기능에 필요한 구성 요소를 사용하여 HTTP 와 같은 서비스를 :

import 'rxjs/add/operator/map';


1

파일에 줄을 추가하십시오.

수입 'rxjs / Rx';

앵귤러 5에서 테스트되었습니다.


0

사실, RxJ는지도 연산자를 별도의 모듈로 분리했으며 이제 다른 연산자처럼 명시 적으로 가져와야합니다.

import rxjs/add/operator/map;

그리고 당신은 괜찮을 것입니다.



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

문제를 해결할 것입니다

각도 5.2.0 및 rxjs 5.5.2에서 테스트했습니다.


0

이것은 rxjs를 사용하고 rxjs 함수가 정적이 아니기 때문에 발생합니다. 즉, 직접 호출 할 수 없으므로 파이프 내부의 메소드를 호출하고 rxjs 라이브러리에서 해당 함수를 가져와야합니다

그러나 rxjs-compat를 사용하는 경우 rxjs-compat 연산자를 가져 오기만하면됩니다.


0

아래 명령을 시도했는데 수정되었습니다.

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


import 'rxjs/Rx';

그것은 단지 당신을 위해 약간의 패치를 수행함으로써 당신이 rxjs 6에서 처음 작업하게하는 것입니다. 단기적인 수정일 뿐이며 전체 rxjs 6 전환이 이루어져야합니다.
HankCa

0

'rxjs / operators'에서 {맵} 가져 오기;

이것은 각도 8에서 나를 위해 작동합니다.


0

@ mlc-mlapis가 언급 한 것 외에도 lettable 연산자와 프로토 타입 패치 방법을 혼합하고 있습니다. 하나 또는 다른 것을 사용하십시오 .

귀하의 경우에는

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.