2017-11-29 2 views
0

Angenommen habe ich die folgenden Funktionen:Erstellen einzelnes Objekt aus mehreren Observable

getUsers() { 
    return Observable.of(['Adam', 'Eve']) 
} 

getUserPets(user) { 
    return Observable.of(user === 'Adam' ? 'Adam pets' : 'Eve pets'); 
} 

getUserKids(user) { 
    return Observable.of(user === 'Adam' ? 'Adam kids' : 'Eve kids'); 
} 

Ich möchte Funktion Abrufen von Benutzern erstellen, ihre Haustiere, Kinder und all diese Daten als einzelnes Objekt zurück. Etwas wie:

getUsersData() { 
    // should return 
    // [ 
    // { user: 'Adam', pets: 'Adam pets', kids: 'Adam kids' }, 
    // { user: 'Eve', pets: 'Eve pets', kids: 'Eve kids' } 
    // ] 
} 

Ich habe versucht, CombineLatest Operator zu verwenden, aber meine Lösung war wirklich chaotisch. Was ist der einfachste (oder am besten lesbare) Weg, eine solche Funktion zu implementieren?

Sandbox: https://stackblitz.com/edit/angular-rspmy9?embed=1&file=app/app.component.ts

Antwort

1

Sie können forkJoin und concatMap für diesen Einsatz:

import { Component } from '@angular/core'; 
import { concatMap, concatAll, map, toArray } from 'rxjs/operators'; 
import { of } from 'rxjs/observable/of'; 
import { forkJoin } from 'rxjs/observable/forkJoin'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: './app.component.html', 
    styleUrls: [ './app.component.css' ] 
}) 
export class AppComponent { 
    constructor() {} 

    getUsers() { 
    return of(['Adam', 'Eve']) 
    } 

    getUserPets(user) { 
    return of(user === 'Adam' ? 'Adam pets' : 'Eve pets'); 
    } 

    getUserKids(user) { 
    return of(user === 'Adam' ? 'Adam kids' : 'Eve kids'); 
    } 

    getUsersData() { 
    return this.getUsers().pipe(
     concatAll(), // unpack the array of users 
     concatMap(user => forkJoin(this.getUserPets(user), this.getUserKids(user)).pipe(
     map(([pets, kids]) => ({ user, pets, kids })) 
    )), 
     toArray(), 
    ); 
    } 
} 

Und dann, wenn Sie zum Beispiel das in einer Vorlage zeigen möchten, müssen Sie verwenden:

{{ getUsersData() | async | json }} 
1

Die Verwendung von combineLatest ist für mich lesbar, aber ich bin mir nicht sicher, wie Ihre Implementierung aussah.

function getUsers() { 
    return Rx.Observable.of(['Adam', 'Eve']) 
} 

function getUserPets(user) { 
    return Rx.Observable.of(user === 'Adam' ? 'Adam pets' : 'Eve pets'); 
} 

function getUserKids(user) { 
    return Rx.Observable.of(user === 'Adam' ? 'Adam kids' : 'Eve kids'); 
} 

const users = getUsers().concatAll() 
    .concatMap(user => Rx.Observable 
    .combineLatest(getUserPets(user), getUserKids(user)) 
    .map(([pets, kids]) => ({user, pets, kids})) 
).toArray(); 

users.subscribe(s => console.log(s)); 

jsbin example

Verwandte Themen