2017-10-26 7 views
-1

私は角度2とRXJS Observablesの初心者です。私は朝から1つのことをやっていますが、それは終わっていますが、私はそれがどのように働いているのか理解できません。ここでRXJS地図とフラットマップ

は私のtest.jsonファイルがAssests/apiフォルダの下にある:その後、私はここで、questionService.tsという名前のこのAPIを公開するサービスを持っている

[ { 
    "name" :"James T", 
    "address": { 
      "Street" : { 
       "data": ["Austin","I","J"] 
      }, 
      "District":"XYZ", 
      "test" : { 
       "insideTest":"insideTest1" 
      } 

    } 
}, 
{ 
    "name" :"James T 2", 
    "address": { 
     "Street" : { 
      "data": ["Austin2","I2","J2"] 
      }, 
      "District":"XYZ 2", 
      "test" : { 
       "insideTest":"insideTest2" 
      } 

    } 
}, 
{ 
    "name" :"James T 3", 
    "address": { 
     "Street" : { 
      "data": ["Austin3","I3","J3"] 
      }, 
      "District":"XYZ 3", 
      "test" : { 
       "insideTest":"insideTest3" 
      } 

    } 
} 

] 

そのコードは次のとおりです。

getTheJsonFile(): Observable<any[]>{ 
     return this._http.get('assets/api/test.json') 
     .map(response=>{ 
      return response.json(); 
     }); 
     } 

そして最後に私のコンポーネントで私はこのサービスを次のように呼んでいます:

import { Component, OnInit } from '@angular/core'; 
import {Campaign} from '../models/campaign'; 
import {Questions} from '../models/questions'; 
import {QuestionService} from '../question/question.service'; 
import { Http , Response, Headers, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 
import "rxjs/add/operator/mergeMap"; 
import 'rxjs/add/operator/do'; 
import 'rxjs/add/operator/toPromise'; 
import 'rxjs/add/operator/share'; 
import 'rxjs/add/operator/switchMap'; 

    @Component({ 
     selector: 'app-campaign', 
     templateUrl: './campaign.component.html', 
     styleUrls: ['../custom.css'], 
     providers: [QuestionService] 
    }) 
    export class CampaignComponent implements OnInit { 


     questionTypes: any; 
     questions: Questions[]; 

    public campaign: Campaign; 
     constructor(public questionService : QuestionService,private _http: Http) { 

     } 


     ngOnInit() { 
     this.getTheJson() 
     .subscribe(data => { 
      console.log("And the data is--->"+data["address"]["Street"]["data"]); 
      data["address"]["Street"]["data"].forEach(test=>console.log("Test Data-->"+test)) 

     }); 
     } 

    getTheJson(): Observable<any>{ 
    return this.questionService.getTheJsonFile() 
     //.map(element => element) 
     //.do(x => console.log("Mydata--->"+JSON.stringify(x))) 
     .flatMap(element => element) 
    } 
    } 

今、私の質問は、getTheJson()メソッドからflatMap(element => element)を取り除くと、null/undefinedを返しています。なぜこれが起きているのですか? また、flatMap()の代わりにmap()を呼び出すと、未定義の結果も返されます。

私はflatMap()を呼び出す必要はありませんが、まったく同じように動作する別のメソッドがありますが、反対側にあります。助けてください!

+0

1.実際に何を達成したいですか?あなたのサービスは実際のJSON全体を返すのですか? –

+1

あなたのコメントアウトされた 'map'呼び出しは何もしません。変更されていない値を返し、その値は配列です。 'flatMap'を使うと、配列の代わりに放射された個々の配列要素が見えます。つまり、配列はストリームにフラット化されます。あなたの 'subscribe'のロギングは、配列ではなく要素のストリームを期待しています。したがって' flatMap'呼び出しでのみ動作します。ところで、 'flatMap'は' mergeMap'のエイリアスです。 – cartant

+0

@cartantは 'flatMap === mergeMap'を知らなかった。ありがとう! – BeetleJuice

答えて

1

デコードされたjsonは、オブジェクトの配列です。 flatMapは、基本的に一度に一つのオブジェクトを発するように観察に変換します:だからあなたがしなければならない

[object, object, object] 

object...object...object... 

flatMapを除去した後、何を購読から取得することはただ一つの値となりこのコードは失敗したので、それに応じて調整します

subscribe(data => { 
      // data["address"] is undefined because you're getting an array of objects 
      data["address"]["Street"]["data"].forEach(test=>console.log("Test Data-->"+test)) 

    }) 

のでflapMapを削除した後、あなたはこのような何かを行うことができます:

subscribe(data => { 
    data.forEach(person => { 
     console.log(`name: ${person.name}`,`street: ${person.address.street.data}`); 
    }); 
}) 
+0

ありがとうございました。それは私を助けた。 – Ankit