2016-05-31 6 views
2

私はangular.ioの例を見つけました。この例は、同じ種類のメソッドを持つ私のアプリに非常に似ています。この例ではPromisesを使用していますが、Observablesを使用しています。このサンプルを参考にしてみると、サービス内のgetHeroメソッドとHeroDetailComponentのngOnInitを除いて、すべてのメソッドがアプリケーションで動作しています。だから、私は構文に問題があるので、誰かが助けてこのメソッドを観察可能なものに変換できるかどうか疑問に思っています。HTTP:Angular 2 + TS HTTPでObservablesを使用する方法

//HeroService 
public getHero(id: string) {  
    return this.getHeroes() 
    .subscribe(heroes => this.heroes.filter(hero => heroes.id === id)[0]); //BTW, what does this [0] mean??   
} 

EDIT:私は実際に直接リストを取得しなければならなかった、それはでは動作しませんでした。ここだから私はこのような何かをしたい、私が観察可能に変換する必要がコードとplunker

//HeroService 
    getHero(id: number) { // my id is String 
    return this.getHeroes() 
       .then(heroes => heroes.filter(hero => hero.id === id)[0]); 
    } 


//HeroDetailComponent 
    ngOnInit() { 
    if (this.routeParams.get('id') !== null) { 
     let id = +this.routeParams.get('id'); 
     this.navigated = true; 
     this.heroService.getHero(id) 
      .then(hero => this.hero = hero); 
    } else { 
     this.navigated = false; 
     this.hero = new Hero(); 
    } 
    } 

です以下の回答に示唆されているようにthis.heroesを返します。実例:

public getById(id: string) { 
    //return this.getHeroes() <---- didn't work 
    return this.http.get('someUrl') // WORKS! 
    .map(heroes => this.heroes.filter(hero => hero.id === id)[0]);   
} 

今、私はまだngOnitに問題があります。なぜ私は本当に理解できません!

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getById(id) 
    //console.log("retrieved id: ",id) <----- gives correct id! 
    .subscribe(hero => this.hero = hero); 
    //console.log("hero: ", this.hero); <----- gives undefined! 
} 

EDIT2、私はあなたがあなたの答えにずっと1つのブラケットを持っていたと思う:(詳細ページに移動しようとしたときに、まだ未定義の取得、ブラケットの正しい場所を見て、取得しよう?

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getById(id) 
    .subscribe(heroes => { 
     // this code is executed when the response from the server arrives 
     this.hero = hero 
    }); 
    // code here is executed before code from the server arrives 
    // even though it is written below 
} 

答えて

2

あなたはSubscriptionが返されObservablesubscribe()を呼び出した場合。あなたは、サブスクリプションにsubscribe()を呼び出すことはできません。

代わりにちょうどオペレータ(map())を使用し、012を使用します呼び出しサイト上:subscribe()に反して

public getHero(id: string) {  
    return this.getHeroes() 
    .map(heroes => this.heroes.filter(hero => heroes.id === id)[0]); 
} 

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getHero(id) 
    .subscribe(hero => this.hero = hero); 
} 

map()Observableで動作するだけでなく、Observableを返します。

[0]は、フィルタリングされたヒーローの最初の項目を取得することを意味します。

更新

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this._searchService.getById(id) 
    .subscribe(searchCase => { 
     // this code is executed when the response from the server arrives 
     this.searchCase = searchCase; 
     console.log("id: ", this.searchCase); 
    }); 
    // code here is executed before code from the server arrives 
    // event though it is written below 
} 

このコードは、加入者のための新たなデータを持っている場合、この機能をsubscribe()に渡されるとObservableのコールされる関数

searchCase => { 
     // this code is executed when the response from the server arrives 
     this.searchCase = searchCase); 
     console.log("id: ", this.searchCase); 
    } 

です。したがって、このコードは直ちに実行されるのではなく、観測データが新しいデータを放出する場合にのみ実行されます。

subscribe()以降のコードはすぐに実行されるため、上記の関数の前に実行されます。したがって、this.searchCaseにはまだ値がありません。

+0

THANKS! getHeroは魅力的に機能しますが、今ではngOnInitに(wierd?)エラーがあります。手伝ってくれますか?私の質問を更新しました! – Alex

+0

答えを更新しました。 –

+0

非常に良い説明、ありがとう!私は一般的にコーディングするのが初めてで、これがどこかに来たことを覚えています。これは、約束とオブザーバブルズの違いの1つです。しかし、私はそれを忘れてしまったと思います!私が移動している詳細ページがまだ未定義であると不平を言っているので、もう一度質問を更新しました!私はあなたが1つのブラケットをあまりにも多く持っていたと思う、または少なすぎる、私は彼らの適切な場所にブラケットを配置しようとしましたが、それはまだ間違っていると思いますか? – Alex

1

これは、あなたがそれを行うことができる方法である。

//HeroService 
public getHero(id: string) {  
    return this.getHeroes() 
     .map(heroes => this.heroes.filter(hero => heroes.id === id)[0]); 
} 

//HeroDetailComponent 
ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getHero(id) 
     .subscribe(hero => { 
      // your code here 
     }); 
} 

[0]は配列のアクセサです。配列インデックス0の最初の要素を選択します。Array.filter()はフィルタリングされた値を持つ新しい配列を返しますが、1つのヒーローだけが必要なので、これが必要です。

-1

良い答え、ここで私は私自身の

サービスは次のようになります追加していて、わずかにそれらを微調整しなければならなかった...

import {Injectable}  from '@angular/core'; 
import {Http, Response} from '@angular/http'; 
import {Person} from '../models/person'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class PersonService { 
    private personsUrl = 'app/data/persons.json'; 

    constructor(private http:Http) { 
    } 

    getPersons():Observable<Person[]> { 
    return this.http.get(this.personsUrl) 
     .map(
     (res:Response) => { 
      let persons = res.json(); 
      return persons || {}; 
     } 
    ) 
     .catch(this.handleError); 
    } 

    getPerson(id:number) { 
    return this.getPersons() 
     .map(persons => persons.filter(person => person.id === id)[0]); 
    } 

    private handleError(error:any) { 
    let errMsg = (error.message) ? error.message : 
     error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
    console.error(errMsg); 
    return Observable.throw(errMsg); 
    } 
} 
+0

本質的な違いは何ですか? –

+0

.map(persons => persons.filter(person => person.id === id)[0]); – danday74

+0

それは質問に関連していないようです。このフィルタ行は既に問題になっており、あなたは 'Hero'を' Person'に改名しました。この答えの目的は何ですか? –

関連する問題