Ankit
Ankit

Reputation: 312

RXJS Map and FlatMap

I am a newbie in angular 2 and RXJS Observables, I am doing one thing since morning, its done but I am not able to get how it is working.

Here is my test.json file under Assests/api folder:

[ {
    "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"
          }

    }
}

]

Then I have a service that expose this api named questionService.ts, Here is the code of that:

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

And finally in my component I am calling this service as:

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

Now my question is if I am removing flatMap(element => element) from getTheJson() method, it is returning null/undefined, why this is happening? And again If I am calling map() instead of flatMap() then also it is returning the Undefined result.

While on other side I have the another method that works exactly same but for that I do not need to call flatMap(). Please help!

Upvotes: 2

Views: 4741

Answers (1)

BeetleJuice
BeetleJuice

Reputation: 40946

Your decoded json is an array of objects. flatMap will basically transform it into an observable that emits one object at a time:

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

After removing the flatMap, what you get from subscribe becomes just one value:

[object, object, object]

So you would have to adjust accordingly because this code fails:

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

    })

So after removing flapMap, you could do something like this:

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

Upvotes: 3

Related Questions