Use fetch instead of ajax with redux-observable

China☆狼群 提交于 2019-12-17 19:34:23

问题


In redux-observable is it possible to use isomporphic-fetch instead of Rx.DOM.ajax?


回答1:


(Note: RX.DOM.ajax is from RxJS v4, and doesn't work with redux-observable which requires RxJS v5. The equivalent in v5 is Rx.Observable.ajax or import { ajax } from 'rxjs/observable/ajax';)

It is indeed possible to use fetch() as well as any other AJAX API; though some adapt easier than others!

The fetch() API returns a Promise, which RxJS v5 has built-in support for. Most operators that expect an observable can consume Promises as-is (like mergeMap, switchMap, etc). But often you'll want to apply Rx operators to the Promise before passing it along to the rest of your Epic, so you'll often want to wrap the Promise inside an Observable.

You can wrap a Promise into an Observable with Observable.from(promise)

Here's an example where I fetch for a user, request the JSON response, then wrap the promise in an observable:

const api = {
  fetchUser: id => {
    const request = fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then(response => response.json());
    return Observable.from(request);
  }
};

You can then consume that in your Epic and apply any operators you want:

const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      api.fetchUser(action.payload) // This returns our Observable wrapping the Promise
        .map(payload => ({ type: FETCH_USER_FULFILLED, payload }))
    );

Here's a JSBin with this working example: https://jsbin.com/fuwaguk/edit?js,output


If you have control over the API code, ideally you would use Observable.ajax (or any other Observable-based AJAX utils) because Promises cannot be cancelled. (as of this writing)




回答2:


Did small adjustment to @jayphelps in order to get that code work for me. Hope this helps to save someone's time.

import { FETCH_USER } from './actions'
import { ofType } from 'redux-observable'
import { map, mergeMap } from 'rxjs/operators'
import { from } from 'rxjs'

const fetchUserEpic = action$ => {
    return action$.pipe(
        ofType(FETCH_USER),
        mergeMap((action = { user: 'redux-observable' }) => {
            const getRequest = (user) => {
                const request = fetch(`https://api.github.com/users/${user}`)
                    .then(response => response.json())
                return from(request)
            }

            return getRequest(action.user).pipe(
               map(payload => ({ type: FETCH_USER_FULFILLED, payload }))
            )
        })
    )
}


来源:https://stackoverflow.com/questions/38589383/use-fetch-instead-of-ajax-with-redux-observable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!