= Caballo Vivo
[quote, CJC] 1177. los cementerios no deben estrenarse enterrando un hombre muerto sino un caballo vivo
Thin, opinionated layer for pure RxJS applications to connect with React-Router (or any router using history
). It has the advantage of scaling well, allowing more concise and expressive code and a better separation between business logic and view layer.
Here's the equivalent implementation of the Redux Reddit advanced tutorial with caballo-vivo, in less than 100 lines of code (https://codesandbox.io/s/caballo-vivo-reddit-w88kg[online sandbox]):
// type localStorage.setItem('cv-log', true) in the console to see the logs! import React from "react" import { render } from "react-dom" import { OrderedMap, Map } from "immutable" import { partialRight } from "ramda" import { Subject, merge, concat, of, from } from "rxjs" import { map, catchError, switchMap } from "rxjs/operators" import { Router, Switch, Route, Link } from "react-router-dom" import { createLocation$, createNavigateTo$, createStore$, history, flog, stow } from "@zambezi/caballo-vivo" import ClipLoader from "react-spinners/ClipLoader" import "./index.css"
const getPosts$ = new Subject()
const pathToIntent = OrderedMap([ ["/:subreddit", ({ subreddit }) => getPosts$.next({ subreddit })], ["/", () => getPosts$.next({ subreddit: "all" })] ])
const location$ = createLocation$(pathToIntent).pipe( // <1> map(location => state => state.set("location", location)) )
const redditJourney$ = getPosts$.pipe( // <2>
switchMap(({ subreddit }) =>
concat(
of(state => state.set("loading", true)), // <3>
from(fetch(https://www.reddit.com/r/${subreddit}.json
)).pipe(
switchMap(res =>
from(res.json()).pipe(
map(json => json.data.children.map(child => child.data))
)
),
stow("subreddit") // <4>
),
createNavigateTo$(subreddit), // <5>
of(state => state.set("loading", false))
)
),
catchError(() =>
of(state => state.set("error", "This subreddit is not available"))
)
)
merge(location$, redditJourney$) .pipe(createStore$(Map()), flog("Render state"), map(toView)) // <6> .subscribe(partialRight(render, [document.getElementById("root")]))
function toView(state) { // <7> if (state.has("error")) return
{state.get("error")}
if (state.get("loading")) return ()
return (