angular - RXJS map 和 FlatMap

标签 angular rxjs observable

我是 Angular 2 和 RXJS Observables 的新手,我从早上开始就在做一件事,它完成了,但我无法了解它是如何工作的。

这是我的 test.json 文件位于 Assests/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"
          }

    }
}

]

然后我有一个公开此 api 的服务,名为 questionService.ts,以下是其代码:

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,为什么会发生这种情况? 如果我调用map()而不是flatMap(),那么它也会返回未定义的结果。

而在另一边,我有另一种方法,其工作原理完全相同,但为此我不需要调用 flatMap()。请帮忙!

最佳答案

解码后的 json 是一个对象数组。 flatMap 基本上会将其转换为一次发出一个对象的可观察对象:

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

删除flatMap后,你从 subscribe 得到的只是一个值:

[object, object, object]

因此您必须进行相应调整,因为此代码失败:

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

关于angular - RXJS map 和 FlatMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46961937/

相关文章:

javascript - javascript 中 rxjs5 组合的示例

angular - Observable 在 Angular 中使用 Http 的好处

rxjs - 当 observable 完成时,我应该如何发出单个值?

rxjs - 只有当它返回的速度比延迟快时,我才能延迟一个 observable

javascript - 与 Angular 2 上的 PandaPay javascript 库集成需要监听 Javascript 方法。如何用 Angular 方法捕捉这个?

angular - 在 angular2 中使用 setElementClass 时,“classList”未定义

css - ngx 分页。我可以使用 Bootstrap 吗?

Angular/RXJS,如何根据特定字符串值对对象的可观察数组进行排序?

javascript - 从可观察数组中获取属性值的总和

angular - 在新的angular2路由器中访问canDeactivate guard中的下一条路由信息