2017-01-03 10 views
0

私はここで、私のユーザサービスで観測可能なオブジェクトをループしようとしています。 Chromeのコンソールはスロー:Observable ObjectをAngular 2でループしようとしているときにエラーが発生しました

error_handler.js:47 EXCEPTION: undefined is not a function

をここに私のコードです:

users.component.ts

import { Component, OnInit } from '@angular/core'; 
import { UserService } from '../user.service'; 
import { Observable } from 'rxjs/Rx'; 
import { User } from '../user'; 

@Component({ 
    selector: 'app-users', 
    templateUrl: './users.component.html', 
    styleUrls: ['./users.component.css'] 
}) 
export class UsersComponent implements OnInit { 

people: Observable<User[]>; 
    constructor(private _userService: UserService) { } 

    ngOnInit() { 
     this.people = this._userService.getAll(); 
     console.log(this.people); 
    } 
} 

users.service.ts

import { Injectable } from '@angular/core'; 
import { Http, Response, Headers } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; 
import { User } from './user'; 


@Injectable() 
export class UserService { 

    private baseurl: string= 'http://swapi.co/api'; 

    constructor(private http: Http) { 
     console.log("User service initialized"); 
    } 


    getAll(): Observable<User[]>{ 
    let users$ = this.http 
     .get(`${this.baseurl}/people`,{headers: this.getHeaders()}) 
     .map(this.mapUsers); 

     return users$; 
    } 


    private getHeaders(){ 
    let headers = new Headers(); 
    headers.append('Accept', 'application/json'); 
    return headers; 
    } 


    mapUsers(response: Response): User[]{ 
     return response.json().results.map(this.toUser); 
    } 


    toUser(r:any): User{ 
    let user = <User>({ 
     id: this.extractId(r), 
     name: r.name 
    }); 
    console.log('Parsed user'+user.name); 
    return user; 
    } 


extractId(personData:any){ 
    let extractedId = personData.url.replace('http://swapi.co/api/people/','').replace('/',''); 
    return parseInt(extractedId); 
} 

} 

users.component.htmlは、

<ul class="people"> 
    <li *ngFor="let person of people | async " > 
     <a href="#"> 
      {{person.name}} 
     </a> 
    </li> 
</ul> 

user.ts

export interface User{ 
    id: number; 
    name: string; 
} 

私はテンプレートからHTMLコードを削除すると、すべてが素晴らしい作品(コンソール上のエラーなし)ので、私は「人のオブジェクトに何か問題があると推測して、明らかにIすることができます応答を繰り返す。みんな、ここでは手に感謝します。

答えて

1

最も可能性が高い理由は、あなたがあなたがコールバック関数内thisを使用する場合は注意する必要がmapコールバック

getAll(): Observable<User[]>{ 
    let users$ = this.http 
    .get(`${this.baseurl}/people`,{headers: this.getHeaders()}) 
    .map(this.mapUsers); 
} 

mapUsers(response: Response): User[]{ 
    return response.json().results.map(this.toUser); 
} 

toUser() {} 

を処理している方法です。文脈によっては、時にはあなたのことが騒がれます。この場合this.map(this.toUser)はクラスインスタンスを指しません。あなたはmapUsers関数内thisのいずれかの用途は、クラスのインスタンスにバインドする必要があることを言っているbind(this)使用するときは、

let users$ = this.http 
    .get(`${this.baseurl}/people`,{headers: this.getHeaders()}) 
    .map(this.mapUsers.bind(this)); 

すなわち

、それをバインドする必要があります。

あなたは矢印の機能を使用する場合、それはまた

let users$ = this.http 
    .get(`${this.baseurl}/people`,{headers: this.getHeaders()}) 
    .map(res => response.json().results.map(this.toUser)); 

レキシカルスコープのコンテキストを保持するとして、あなたは、この区別を心配する必要はありません、でもtoUser機能を渡すと、あなたがそうであるように、同じ問題を抱えていますthis.extractId(r)を使用してください。あなたもそれをバインドする必要があります

mapUsers(response: Response): User[]{ 
    return response.json().results.map(this.toUser.bind(this)); 
} 
+0

ありがとう、あなたには返信のためのpesskillet。それを知ってよかったです..私はそれを念頭に置いておきます。私はマップ呼び出しを更新して関数を変更しました:.map(this.mapUsers.bind(this)); ...コンソールがスローされました: モジュールビルドに失敗しました:エラー:/home/webdeveloper/Workspace/Angular2/unibague_directory_v2/src/app/user.service.ts(26,14):タイプ 'Observable <{}> 'はタイプ' Observable 'に割り当てられません。 タイプ '{}'はタイプ 'User []'に割り当てられません。 –

+0

2番目のオプション(res =>)を使用すると、コードエディタ(Visual Studio)が「応答」という単語に下線を引いています。 (変数が宣言されていない) –

+0

まあ、ええ、それはタイプミスでした。それは 'res'ではなく' response'でなければなりません –

関連する問題