typescript - Rxjs Transformiraj rezultat API Observable u drugi Observable u funkciji servisa


Imam servis za učitavanje čiji je rezultat Observable<string> koji sadrži CSV datoteku. Svaki redak predstavlja različiti entitet (npr. objekta Osoba), a dijelovi razdvojeni zarezom predstavljaju svojstva osobe, na primjer id, dob, ime itd.

Funkcija usluge učitavača je:

loadtTextFile(path: string): Observable<string> 

Funkcija servisa loadAllPerson je:

loadAllPerson(): Observable<Array<Person>> 

Želio bih pozvati loadtTextFile u omotaču loadAllPerson gdje je potreban izlaz: Observable<Array<Person>>

Kako mogu osigurati da usluga vrati rezultat tek kada su svi redovi CSV-a parsirani u rezultat Observable<Array<Person>>?

Vjerojatno bismo se prvo trebali čekati rezultat loader service, zatim ga parsirati u niz Person i vratiti rezultat u Observable<Array<Person>>

Sljedeći dio koda parsira sadržaj u niz osoba, gdje je contentObservable Observable<string>

const contentObservable = this.fileLoaderService.loadtTextFile();

contentObservable.mapTo(fileContent => {
    const rowsOfContent = fileContent.split('\n');
    rowsOfContent.forEach((row: string) => {
      const cols = row.split(',');
      // has valid numeric value of id and age?
      if (!Number.isNaN(+cols[0]) && !Number.isNaN(+cols[3])) {
        const person = new Person(+cols[0], cols[1], cols[2], +cols[3], cols[4],
          cols[5], cols[6], cols[7], new Date(cols[8]));
        personData.push(person);
      }
    });
    console.log(JSON.stringify(personData));
});

Odgovor #1

Operator map je vaš prijatelj. Pokušajte ovako:

loadAllPerson(): Observable<Person[]> {
  return loadTextFile(PATH).pipe(
    map((csv: string) =>
      csv.split('\n')
         .map((rows: string[]) => rows.map((row: string) => row.split(',')))
         .map((table: string[][]) => 
           table.filter((cols: string[]) => !Number.isNaN(+cols[0]) && !Number.isNaN(+cols[3]))
                .map((cols: string[]) => new Person(+cols[0], cols[1], cols[2], +cols[3], cols[4], cols[5], cols[6], cols[7], new Date(cols[8])))
         )
    )),
  );
}