2016-07-11 15 views
1

Spielend mit RxJS und reagieren, habe ich Probleme, wie auf Daten in Observable.fromPromise in der Karte auf einem anderen Observable generiert zu warten.Wie Observable.flatMap zu warten, um zu lösen

Ich habe Asynchron-Helfer:

const dataStreamGenerator = (url = CLIENTS_DATA_URL) => (
    Rx.Observable.fromPromise(fetch(url)) 
    .flatMap(response => Rx.Observable.fromPromise(response.json())) 
    .catch(err => Rx.Observable.of(new Error(err))) 
); 

Dann habe ich actions.fetchClients$ die Rx.Subject ist:

actions.fetchClients$.map((url = CLIENTS_DATA_URL) => { 
    const ts = Date.now(); 
    console.log('FETCH CLIENTS with: ', url); 
    return dataStreamGenerator(url); 
    }).map(val => { 
    console.log('GOT DATA IN REDUCER: ', val); 
    const error = (val instanceof Error) ? val.message : undefined; 
    const data = error ? undefined : val; 
    actions.receivedClientsData$.next({ data, error, ts: Date.now() }); 
    return (state) => state; 
    }) 

(Ja, versucht Redux in RxJS mimick).

Whan Ich teste die dataStreamGenerator, ist es ok funktioniert (mit ava) und liefert Daten:

test('dataStreamGenerator', t => { 
    const ds$ = dataStreamGenerator(CLIENTS_DATA_URL); 
    return ds$.do((data) => { 
    t.is(data.length, 10); 
    }); 
}); 

(AVA automatisch auf beobachtbare abonnieren und verbrauchen es, so gibt es keine Notwendigkeit zu abonnieren).

Aber die actions.fetchClients$.map((url = CLI... zweite Karte (ab ... console.log('GOT DATA IN REDUCER: ', val);... noch die beobachtbaren und nicht die Daten von Datastream $ bekommen.

habe ich versucht, alle möglichen Kombinationen von map und flatMap in fetchClients Code $, aber noch kein Glück.

Mein Testcode ist:

test.only('fetchClients$', t => { 
    const initialState = {}; 
    actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users'); 
    reducer$.subscribe(val => { 
    console.log('TEST SUBSCRIBE VAL: ', val); 
    t.pass(); 
    }); 
    actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users'); 
}); 

ich kann nicht herausfinden, wie man die beobachtbaren dataStreamGenerator(url); warten Daten ein auszusenden nd nicht das Observable.

Danke.

Antwort

2

Sie müssen die Ergebnisse dessen, was Sie von dataStreamGenerator zurückgegeben haben, reduzieren.

actions.fetchClients$ 
    //This is now a flatMap 
    .flatMap((url = CLIENTS_DATA_URL) => { 
    const ts = Date.now(); 
    console.log('FETCH CLIENTS with: ', url); 
    return dataStreamGenerator(url); 
    }); 

Der map Operator liefert den Wert stromabwärts, wie sie ist, während flatMapObservables abflachen wird, Arrays und Promises, so dass ihre Werte sind, was weitergegeben wird.

Es funktioniert in dem Testfall, weil Sie das Observable direkt abonnieren, das von dataStreamGenerator zurückgegeben wird.

+0

Dank @paulpdaniels. Ich habe das schon mal probiert, war aber von der Testausgabe verblüfft. Es scheint, dass das ganze Problem mit ava ist - nicht darauf warten, dass das Fetch gelöst und vorzeitig beendet wird (nach dem ersten gelieferten Wert). Ich sollte 'Ava' zu Tags hinzufügen. – DavidC

Verwandte Themen