npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-epic

v0.3.0

Published

Better Redux Async and Prefetching

Downloads

53

Readme

Redux-Epic

Greenkeeper badge

Better async in Redux with SSR data pre-fetching

Redux-Epic is a library built to do complex/async side-effects and server side rendering(SSR) data pre-fetching using RxJS.

NOTE:

With the release of RxJS@5, I'm recommending everyone move to redux-observable. This library will soon be deprecated as soon as the API is close enough to make the transition easier. With this latest release, we change the API of epics (in a non-breaking way) to make the signatures the same as redux-observable epics.

The last piece of the puzzle is SSR. I've created react-redux-epic to add SSR to Redux Observable in the same fashion as Redux-Epic.

Current Async story in Redux

There are currently two different modes of handling side-effects in Redux. The first is to dispatch actions that are functions or actions that contain some sort of data structure. Here are some common examples:

  • redux-thunk: dispatch action creators (functions) instead of plain action objects
  • redux-promise: dispatch promises(or actions containing promises) that are converted to actions

The downside of these two libraries: you are no longer dispatching plain serializable action objects.

The second and cleaner mode is taken by redux-saga. You create sagas (generator functions) and the library converts those sagas to redux middleware. You then dispatch actions normally and the sagas react to those actions.

Redux-Epic makes async better

While Redux-Saga is awesome and a source of inspiration for this library, I've never been sold on generators themselves. They are a great way to create long lived iterables (you pull data out of them), it just doesn't make sense when you want something to push data to you instead. Iterables (generators create iterables) are by definition not reactive but interactive. They require something to be constantly polling (pulling data out) them until they complete.

On the other hand, Observables are reactive! Instead of polling the iterable, we just wait for new actions from our observables and dispatch as normal.

Why create Redux-Epic?

  • Observables are powerful and proven

    • Allows Redux-Epic to offer a smaller API surface
    • Allows us to easily do server side rendering with data pre-fetching
  • The Epic approach is a cleaner API

    • Action creators are plain map functions. In other words, they take in data and output actions
    • Components are can be plain mapping functions. Take in data and output html.
    • Complex/Async application logic lives in epics.
  • Server Side Rendering depends on async side-effects, which is why it's built into Redux-Epic

Observables offer a powerful and functional API. With Redux-Epic we take advantage of this built in power and leave our specific API as small as possible.

Install

npm install --save redux-epic

Basic Usage

Let's create a Epic, a function that returns an observable stream of actions, that handles fetching user data

// fetch-user-epic.js
import { Observable } from 'rx';
import fetchUser from 'my-cool-ajax-library';

export default function tickEpic(actions$) {
  return action$
    // only listen for the action we care about
    // this will be our trigger
    .filter(action.type === 'FETCH_USER')
    .flatMap(action => {
      const userId = action.payload;
      // fetchUser makes an ajax request and returns an observable
      return fetchUser(`/api/user/${userId}`)
        // turn the result of the ajax request
        // into an action
        .map(user => { return { type: 'UPDATE_USER', payload: { user: user } }; })
        // handle request errors with another action creator
        .catch(error => Observable.just({ type: 'FETCH_USER_ERROR', error: error }));
    });
}

Now to start using your newly created epic:

import { createEpic } from 'redux-epic';
import { createStore, applyMiddleware } from 'redux'
import myReducer from './my-reducer'
import fetchUserEpic from './fetch-user-epic'

// createEpic can take any number of epics
const epicMiddleware = createEpic(fetchUserEpic);

const store = createStore(
  myReducer,
  applyMiddleware(epicMiddleware);
);

And that's it! Your epic is now connected to redux store. Now to trigger your epic, you just need to dispatch the 'FETCH_USER' action!

Docs

Previous Art

This library is inspired by the following

Redux-Observable

It's come to my attention the recent changes to the library redux-observable.

Initially redux-observable was very different from redux-epic. They took the same path as redux-thunk, redux-promise, and others where the observable (or promise, or function, or whatever) goes through the dispatch. This was distasteful to me, which is why I went the same route as redux-saga and redux-saga-rxjs, using middleware to intercept and dispatch actions in a fashion that fits the idioms of both Redux and Rx.

It looks like they independently came to the same conclusion in https://github.com/redux-observable/redux-observable/pull/55 and https://github.com/redux-observable/redux-observable/pull/67 and switched to an identical model as mine, even the same name! It's great that we both came to the same conclusions and validates my initial thoughts.

After a conversation with the authors of Redux-Observable, we've decided to join forces. More details to come as to exactly how that would work.

I recommend using Redux-Observable over this library unless you need server side data fetcing today.