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-ready-wrapper

v1.1.15

Published

Ready wrapper middleware for Redux library

Downloads

10

Readme

NOTE: This repo is deprecated and archived. Please use redux-thunk-init instead.

What is redux-ready-wrapper?

npm version build status npm downloads

  • A middleware of Redux library that handles asynchronous action flow.
  • If you are familiar with redux-thunk, you probably already know how to use redux-ready-wrapper, as alternative.
  • This middleware allows us to return a higher-order function (ready / wrap) of "thunk" in action creator instead of an action, by accepting a callback function as argument.

API

a) ready - function which accepts two arguments and returns "thunk" function that eventually returns a Promise:

  • callback (mandatory) - A callback function that will receive dispatch and getState methods from redux's store object.

  • options (optional, default: {}) - A user defined options to be passed as second argument and assigned to ready action (the object), in this form:

{
  type: 'READY_ACTION',
  options: /* your options values */
}

Once ready is invoked, it will dispatch additional ready action BEFORE dispatching the next targeted action in callback. It could be useful if you plan to have a generic reducer for some controls with provided options during the "ready" phase.

b) wrap - function which is similar to ready, except it only accepts one callback argument without dispatching ready action:

  • callback (mandatory) - A callback function that will receive dispatch and getState methods from redux's store object.

Using wrap instead of ready if you just need asynchronous handling without having ready action to be dispatched.

Installation

  • To install package:
npm install redux-ready-wrapper --save
  • import and apply middleware:
import { createStore, applyMiddleware } from "redux";
import { createLogger } from "redux-logger";
import readyWrapper from "redux-ready-wrapper"; // <--- import this
import rootReducer from "./reducer";

// add middleware by calling it!
const middlewares = [readyWrapper()];

if (process.env.NODE_ENV !== "production") {
  middlewares.push(createLogger());
}

export default createStore(rootReducer, applyMiddleware(...middlewares));

Usage

  • Example 1:
import { wrap } from "redux-ready-wrapper"; // <--- import `wrap` and/or `ready`
import { SOMETHING, SOMETHING_NEW } from "./constants";

// return `wrap` function instead
// so that we can implement promise chaining
export function doSomething() {
  return wrap(dispatch =>
    dispatch({
      type: SOMETHING,
      payload: {
        key1: "value1",
        key2: "value2"
      }
    })
  );
}

// extend received action (the source) and return it as new action
export function extendSomething(action = {}) {
  const payload = { ...action.payload, key2: "new value 2", key3: "value 3" };
  const newAction = { ...action, type: SOMETHING_NEW, payload };

  return newAction;
}

// do something else with newly extended action or,
// throw error if it is invalid.
export function doSomethingElse(action = {}) {
  if (action.type !== SOMETHING_NEW) {
    throw new Error("Invalid new action received!");
  }

  console.log(`Yay! new action received:  ${JSON.stringify(action)}`);

  return action;
}

// assumed `store` object is available:
const { dispatch } = store;

dispatch(doSomething())
  .then(dispatched => extendSomething(dispatched)) // extend dispatched action from `doSomething`
  .then(extended => dispatch(doSomethingElse(extended))) // passing extended action to `doSomethingElse` and dispatch
  .catch(error => alert(`Oops! ${error}`)); // alert thrown error message if invalid action
  • Provide options as second argument to ready function and deal with reducers, eg:
// dispatch action from action creator with options provided
export function doSomething() {
  const options = {
    key1: "value1",
    key2: "value2"
  };

  return ready(dispatch => dispatch(actionCreator()), options);
}

// add a reducer say, `something` pure function
export function something(state = {}, action) {
  if (action.type === "READY_ACTION") {
    // manage state change and `action.options`
  } else if (action.type === "SOMETHING") {
    // manage state change for `SOMETHING`
  }

  return state;
}
  • Example 2 (React-Redux):
// filename: userActions.js

import { ready } from 'redux-ready-wrapper';
import { LOGIN_NOTIFICATION } from './constants';

// dispatch user login notification
// message could be handled in your middleware
export function showLoginNotification(message) {
  return {
    type: LOGIN_NOTIFICATION,
    message
  };
}

// user login action
export function userLogin(formData) {
  return ready(dispatch => (
    fetch('/login', { method: 'POST', body: formData })
    .then(response => response.json())
    .then(user => {
      if (!user.id) throw new Error('Login failure. Please try again!');
      return dispatch(showLoginNotification('You have logged in!'));
    })
    .catch(error => dispatch(showLoginNotification(error)))
  ));
}

// proceed to the next action after user logged in
export function doNextAfterLoggedIn() {
  return ready((dispatch, getState) => {
    const current = getState();
    ...
  });
}
// filename: User.js
// User react component that has `handleSubmit` method
// and with bound user actions in `mapDispatchToProps`

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as userActions from './userActions';

class User extends Component {
  ...

  // say, invoked through `onSubmit` via user login form
  // and proceed to next once logged in successfully
  handleSubmit(evt) {
    evt.preventDefault();
    const { userLogin, doNextAfterLoggedIn } = this.props.actions;
    const formData = ...;

    // note that promise here is from `fetch`
    userLogin(formData)
    .then(() => doNextAfterLoggedIn());
  }

  ...
}

const mapStateToProps = ...;
const mapDispatchToProps = dispatch => ({
  actions: bindActionCreators(userActions, dispatch)
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(User);

Note: You may not need to return the wrapper in all action creators. It should only be used based on the context.

  • Returning function from action creator without using ready / wrap:
export function actionCreator() {
  // return a function in action creator with received `store` object
  return store => {
    // do something with `store.dispatch()`
    // or with 'store.getState()'
  };

  // or, return function by using object destructuring approach
  return ({ dispatch, getState }) => {
    // do something with `dispatch()`
    // or with 'getState()'
  };
}

License

MIT