简体   繁体   中英

Typescript flatten array with RXJS

I'm banging my head with an issue I'm having with a RXJS transformation in a Ionic 2 application. I'd like to flat a json file into object, this is my semplified json file

    [{
     "lingua": "it",
     "labels": {
        "denominazione": "Hi",
     },
     "tipologie": [
      {"denominazione": "test 1"},
      {"denominazione": "test 2"}
    ]
    },...]

this is the snippet of typescript code

    export class MyRecord{
       denominazione: string;
       label_denominazione: string;

       constructor(denominazione: string, label_denominazione: string) {
          this.denominazione = denominazione;
          this.label_denominazione = label_denominazione;
       }
    }

    public getRecords() {
       var url = '../assets/records.json'; 
       let records$ = this.http
          .get(url)
          .map(mapRecords);
    return records$;

    function mapRecords(response: Response): MyRecord[] {
       return response.json().filter(x => x.lingua == "it")
        .map(({ lingua, labels, tipologie }) => tipologie.map(tipologia =>
        toMyRecord(labels, tipologia))
       );
    }

    function toMyRecord(l: any, t: any): MyRecord{
      let record= new MyRecord(
        t.denominazione,
        l.denominazione,
      );
      return record;
    }

When I call the service:

    members: MyRecord[];
    this.myService.getRecords().subscribe(res => {
        this.members = res;
        },
        err => console.log(err)
    );

What I get in this.members is an array of array of MyRecord :

    [[{ label_denominazione: "Hi", denominazione: "test 1"}, { label_denominazione: "Hi", denominazione: "test 2"} ]]

instead of an array of MyRecord:

    [{ label_denominazione: "Hi", denominazione: "test 1"}, { label_denominazione: "Hi", denominazione: "test 2"} ]

I've tried to use flatMap (mergeMap), but I've got the error 'flatMap is not a function' (btw I've imported the operator mergeMap). I'm also wondering as this.members defined as MyRecord array can accept a different type.

Here seems to be a problem:

function mapRecords(response: Response): MyRecord[] {
   return response.json().filter(x => x.lingua == "it")
    .map(({ lingua, labels, tipologie }) => tipologie.map(tipologia =>
    toMyRecord(labels, tipologia))
   );
}

instead of 1st map try reduce like this, which merges mappings:

function mapRecords(response: Response): MyRecord[] {
   return response.json().filter(x => x.lingua == "it")
      .reduce((result, current, idx) => 
          result.concat(current.topologie.map(tipologia =>
              toMyRecord(current.labels, tipologia)));
      }, []);
}

and it should do the thing.

response.json() returns a plain object, not an observable. From that point forward you're operating on a simple Array with the standard Array methods, which do not include flatMap .

You could convert that into an observable with Observable.from but I don't see the point in doing that based on the operation you're doing in the example. Just use a different strategy to map/reduce that Array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM