尝试在Angular 2

时间:2017-01-03 00:57:21

标签: json http angular typescript observable

我在这里试图在我的用户服务上循环可观察对象。 Chrome的控制台抛出:

  

error_handler.js:47 EXCEPTION:undefined不是函数

这是我的代码:

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代码时,一切都运行良好(在控制台上没有错误)所以,我猜这些&#39;人员&#39;对象,显然我无法反复回应。拜托,伙计们,欢迎来到这里。

1 个答案:

答案 0 :(得分: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)时,您说this函数中mapUsers的任何用法都应绑定到类实例。

当你使用箭头函数时,你不必担心这种区别,因为它保留了词法范围上下文

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