2017-05-02 12 views
2

以下のコードでgetCurrentPositionEpicをコメントアウトすると、アプリケーションが動作します。redux-observableアクションはプレーンなオブジェクトでなければなりません。

Actions must be plain objects. Use custom middleware for async actions.

export const rootEpic = combineEpics(
    fetchCategoriesEpic, 
    getCurrentLocationEpic, 
    getCurrentPositionEpic 
) 

const store = createStore(
    rootReducer, 
    initialState, 
    composeWithDevTools(
    applyMiddleware(createEpicMiddleware(rootEpic)) 
) 
) 

location.epic.js

const getCurrentPosition$ = getCurrentPositionObservable(
    { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } 
) 

getCurrentPosition$.subscribe(
    (position) => { 
    console.log(position) 
    const positionObject = { 
     lat: position.coords.latitude, 
     lng: position.coords.longitude 
    } 
    //store.dispatch(updateRegion(positionObject)) 
    //getCurrentLocation(positionObject) 
    }, 
    (err) => { 
    console.log('Error: %s', err) 
    }, 
() => { 
    console.log('Completed') 
    }) 

export const getCurrentLocationEpic = action$ => 
    action$.ofType(GET_CURRENT_LOCATION) 
    .mergeMap(() => 
     Observable.fromPromise(Geocoder.geocodePosition(makeSelectLocation())) 
     .flatMap((response) => Observable.of(
      getCurrentLocationFulfilled(response) 
     )) 
     .catch(error => Observable.of(getCurrentLocationRejected(error))) 
    ) 

export const getCurrentPositionEpic = action$ => 
    action$.ofType(GET_CURRENT_POSITION) 
    .mapTo(() => getCurrentPosition$ 
     .flatMap((response) => Observable.of(
     getCurrentPositionFulfilled(response) 
    )) 
     .catch(error => Observable.of(getCurrentLocationRejected(error))) 
    ) 

以下のコードを変換するために使用されるだけのヘルパーですネイティブnavigator.geolocation.getCurrentPositionを反応:私が残した場合でも、それは私がエラーを取得するコメント解除しましたコールバックを取る関数の代わりに観測することができます。エラーの原因となることができるもの

callBackToObservable.js

import { Observable } from 'rxjs' 

export const getCurrentPositionObservable = Observable.bindCallback(
    (options, cb) => { 
    if (typeof options === 'function') { 
     cb = options 
     options = null 
    } 
    navigator.geolocation.getCurrentPosition(cb, null, options) 
    }) 

export const getCurrentPositionFulfilledEpic = (action$, store) => 
    action$.ofType(GET_CURRENT_POSITION_FULFILLED) 
     .mergeMap(() =>{ 
    console.log(store)***************** store is populated here 
    return Observable.fromPromise(Geocoder.geocodePosition({ 
    lat: store.getState().get('searchForm').get('position').lat,***but not here 
    lng: store.getState().get('searchForm').get('position').lng 
    })) 
    .flatMap((response) => Observable.of(
     getCurrentLocationFulfilled(response) 
    )) 
    .catch(error => Observable.of(getCurrentLocationRejected(error))) 
} 
) 

https://github.com/devfd/react-native-geocoderを使用してGeocoder.geocodePosition

答えて

3

のために問題がmapToの使用状況です:店で渡ししようと

。あなたは基本的には「Observableにこのアクションをマップする」と言っているので、あなたの叙事詩はObservable of Actionsの代わりにObservable of actions Observable<Observable<Action>>を返します。

あなたの叙事詩は、現在、放射行動の代わりにオブザーバブルを放出しています。代わりにmergeMap,switchMapなどのマージストラテジ演算子を使用して、内側のObservableチェーンを最上位レベルにフラット/マージするためにマージする必要があります。 flatMapは、mergeMap、btwの別名です。

export const getCurrentPositionEpic = action$ => 
    action$.ofType(GET_CURRENT_POSITION) 
    .mergeMap(() => getCurrentPosition$ 
     .flatMap((response) => Observable.of(
     getCurrentPositionFulfilled(response) 
    )) 
     .catch(error => Observable.of(getCurrentLocationRejected(error))) 
    ) 

もうひとつ - あなたはそれが1だからgetCurrentPosition$からgetCurrentPositionFulfilledアクションをマッピングするためにflatMap別名mergeMap使用する必要はありません:1。それが1対多数であれば、それが必要になります。

export const getCurrentPositionEpic = action$ => 
    action$.ofType(GET_CURRENT_POSITION) 
    .mergeMap(() => getCurrentPosition$ 
     .map((response) => getCurrentPositionFulfilled(response)) 
     .catch(error => Observable.of(getCurrentLocationRejected(error))) 
    ) 

はそれをあなたの方法を使用しても、実際のありませんが、それは後でコードを維持する他の人を混乱させる可能性があります。

関連する問題

 関連する問題