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-resource-wlfe

v1.0.0

Published

Easily create redux actions for managing server resources

Downloads

4

Readme

redux-resource

Circle CI

Easily create actions for managing server resources like fetching, creating, or updating. Provide action types used in your reducer function for updating your redux store based on results from the server.

Install

$ npm install redux-resource

Usage

Use createResourceAction to create an action for fetching a resource. Supply a URL (with optional path parameter placeholders) along with three action types to represent the act of sending the request, receiving a successful response from the server, and receiving an error from the server. Make sure to use these action types in your reducer function!

import { createResourceAction } from 'redux-resource';

const fetchTodo = createResourceAction(
  '/todos/:id', 'FETCH_TODO', 'RCV_TODO', 'ERR_RCV_TODO'
);

When calling the action, pass in any parameters to fill in the placeholders or add additional search query parameters.

// make request to '/todos/42'
store.dispatch(fetchTodo({ id: 42 }));

// make request to '/todos/42?extraParam=hi'
store.dispatch(fetchTodo({
  id: 1,
  extraParam: 'hi'
}));

createResourceAction defaults to GET requests. To use other verbs swap out the URL string with an object literal that defines the URL and HTTP verb.

const addTodo = createResourceAction(
  { url: '/todos/add', method: 'POST' },
  'ADD_TODO', 'ADDED_TODO', 'ERR_ADDING_TODO'
);

You can also supply headers inside the object literal. This is useful if your request content type needs to be something other than application/json.

const resource = {
  url: '/todos/add',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
};

const addTodoFromForm = createResourceAction(
  resource, 'ADD_TODO', 'ADDED_TODO', 'ERR_ADDING_TODO'
);

In addition to taking parameters, the action can take request data. You can pass in null for params if you don't have any.

// make request to '/todos/add' with JSON '{"title":"Finish tests"}'
store.dispatch(
  addTodo(null, { title: 'Finish tests' })
);

// make request to '/todos/add' with form data 'title="Add%20more%20features"'
store.dispatch(
  addTodoFromForm(null, { title: 'Add more features' })
);

Actions return a thunk (an anonymous function). To use the actions with your store you must include the middleware. (redux-resource uses redux-thunk under the hood.)

// configureStore.js

import { applyMiddleware, createStore } from 'redux';
import { resourceMiddleware } from 'redux-resource';
import myReducer from './myReducer';

const createStoreWithMiddleWare = applyMiddleware(resourceMiddleware)(createStore);
const store = createStoreWithMiddleWare(myReducer);

Make sure to add the action types to your reducer function!

function reducer(state = INITIAL_STATE, action) {
  switch(action.type) {
    case 'FETCH_TODO':
      // ...

    case 'RCV_TODO':
      return { ...state, todo: action.payload };

    case 'ADD_TODO':
      // ...

    case 'ERR_ADDING_TODO':
      return { ...state, error: action.payload };

    // etc.

    default:
      return state;
  }
}

Dispatching the actions will return a promise that resolves when a request succeeds or fails. Therefore, catch won't work on failed requests. Your reducer should manage how your state reacts to failed requests. This allows you to gracefully handle state changes from errors for React applications for example.

// Successful request
store.dispatch(fetchTodo({ id: 42 })).then(() => {
  const todo = store.getState().todo;
});

// Failing request
store.dispatch(addTodo(null, { title: 'Finish tests' })).then(() => {
  const error = store.getState().error;
});

API

createResourceAction

createResourceAction(
  url: string | {
    url: string,
    [method: string],
    [headers: Object]
  },
  sendType: string,
  successType: string,
  errorType: string
)

url - URL for resource. Allows path parameter placeholders like /users/:id.

sendType - The action type when dispatching the request.

successType - The action type when successfully receiving back the resource from the server.

errorType - The action type when a server request fails.

Example

import { applyMiddleware, createStore } from 'redux';
import { resourceMiddleware, createResourceAction } from 'redux-resource';

const createStoreWithMiddleWare = applyMiddleware(resourceMiddleware)(createStore);

const INITIAL_STATE = {
  fetching: false,
  user: null,
  error: null
};

function reducer(state = INITIAL_STATE, action) {
  switch(action.type) {
    case 'FETCH_USER':
      return { ...state, fetching: true };

    case 'RECEIVE_USER':
      return { ...state, fetching: false, user: action.payload };

    case 'ERR_RECEIVE_USER':
      return { ...state, fetching: false, error: action.payload };

    default:
      return state;
  }
}

const store = createStoreWithMiddleWare(reducer);

const fetchUser = createResourceAction(
  '/users/:id', 'FETCH_USER', 'RECEIVE_USER', 'ERR_RECEIVE_USER'
);

store.dispatch(fetchUser({ id: 1 }))
  .then(() => console.log(store.getState()));

// {
//   fetching: false,
//   user: { id: 1, name: 'Jeremy' },
//   error: null
// }