2017-01-03 26 views
0

我在這裏試圖在我的用戶服務上循環觀察對象。 的Chrome瀏覽器的控制檯拋出:錯誤嘗試循環Angular 2中的Observable對象

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代碼,一切(控制檯上沒有錯誤)的偉大工程的話,我想沒有什麼毛病「人」的對象,很明顯,我可以不會迭代響應。請大家,一手將在這裏讚賞。

回答

1

最可能的原因是要處理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內回調函數時要小心的方式。上下文有時會讓你失望。在這種情況下,this中的.map(this.toUser)不指向類實例。您需要將其綁定,即

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

當您使用bind(this)你說,mapUsers函數中的任何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 yor回覆。很高興知道..我會記住它。我修改了函數,更新了地圖調用:.map(this.mapUsers.bind(this)); ...但現在控制檯拋出: 未捕獲的錯誤:模塊構建失敗:錯誤:/home/webdeveloper/Workspace/Angular2/unibague_directory_v2/src/app/user.service.ts(26,14):Type'Observable <{}> '不可分配鍵入'Observable '。 類型'{}'不可分配爲鍵入'User []'。 –

+0

如果我使用第二個選項(res =>),我的代碼編輯器(visual studio)強調了「響應」一詞。 (變量未聲明) –

+0

嗯,是的,這是一個錯字。它應該是'響應',而不是'res' –