Después de consultar con expertos en esta materia, programadores de varias áreas y profesores dimos con la respuesta al problema y la compartimos en este post.
Solución:
(Nota: RX.DOM.ajax
es de RxJS v4y no funciona con redux-observable
que requiere RxJS v5. El equivalente en v5 es Rx.Observable.ajax
o import ajax from 'rxjs/observable/ajax';
)
De hecho, es posible utilizar fetch()
así como cualquier otra API de AJAX; ¡aunque algunos se adaptan más fácilmente que otros!
Él fetch()
La API devuelve un Promise
que tiene RxJS v5 soporte incorporado para. La mayoría de los operadores que esperan un observable pueden consumir Promises tal cual (como mergeMap
, switchMap
, etc). Pero a menudo querrá aplicar operadores Rx a la Promesa antes de pasarla al resto de su Epic, por lo que a menudo querrá envolver la Promesa dentro de un Observable.
Puedes envolver una Promesa en un Observable con Observable.from(promise)
Aquí hay un ejemplo en el que busco un usuario, solicito la respuesta JSON y luego envuelvo la promesa en un observable:
const api =
fetchUser: id =>
const request = fetch(`https://jsonplaceholder.typicode.com/users/$id`)
.then(response => response.json());
return Observable.from(request);
;
Luego puede consumir eso en su Epic y aplicar los operadores que desee:
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 ))
);
Aquí hay un JSBin con este ejemplo de trabajo: https://jsbin.com/fuwaguk/edit?js,output
Si tiene control sobre el código API, idealmente usaría Observable.ajax
(o cualquier otra utilidad AJAX basada en Observable) porque las Promesas no se pueden cancelar. (a partir de este escrito)
Hice un pequeño ajuste en @jayphelps para que ese código me funcionara. Espero que esto ayude a ahorrar tiempo a alguien.
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 ))
)
)
)
Si para ti ha sido útil nuestro post, sería de mucha ayuda si lo compartes con más programadores de este modo nos ayudas a dar difusión a nuestro contenido.