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-crud-async

v0.8.1

Published

crud async actions for redux

Downloads

50

Readme

redux-crud-async

Build Status

redux-crud-async will create CRUD async actions and states automatically, just for you. The configuration is minimalist.

It currently uses axios or sails.io websocket (custom socket.io) for XHR. It allows you to use a REST API with authentication with a Bearer Token. In a near future, I will implement the possibility to create random actions like sign_in, sign_out or tranformThisLeadInGold Redux-crud-async is built against 150+ tests. Unfortunately this does not mean that redux-crud-async is bug free, please send issues if you find one !

Table of Contents

  1. Setup
  2. Conventions a. Routes b. Authentication c. Socket
  3. Configuration
  4. Actions a. Names b. Additionnal Actions
  5. States (Reducers)
  6. Todo
  7. Change Log

Setup

NPM

you can find it on NPM

npm i -S redux-crud-async

ActionTypes

// redux/actionTypes/index.js
  var reduxCrudAsync = require('redux-crud-async')
  var crud = new reduxCrudAsync()

  module.exports = {
    ...crud.primaryActionTypesFor('channel'),
    ...crud.primaryActionTypesFor('tag'),

    ...crud.associationActionTypesFor('channel', 'tag')
  }

Actions

// redux/actions/index.js
  var reduxCrudAsync = require('redux-crud-async')

  var hostConfig = {
    host            : 'https://my-api.com',
    prefix          : 'v1', // Optional - default to ''
    pluralizeModels : false, // Optional - default to true

  }

  var crud = new reduxCrudAsync(hostConfig) // hostConfig is mandatory for actionsGenerator

  module.exports = {
    ...crud.primaryActionsFor('channel'),
    ...crud.primaryActionsFor('tag'),

    ...crud.associationActionsFor('channel', 'tag')
  }

Reducers

// redux/reducers/index.js
  var reduxCrudAsync = require('redux-crud-async')
  var crud = new reduxCrudAsync()

  module.exports = {
    ...crud.primaryReducerFor('user'),
    ...crud.primaryReducerFor('pet'),

    ...crud.associationReducerFor('user', 'pet')
  }

EXEMPLE USAGE Click here to see how much it is easy to use this module


Conventions

General

It might be obvious but all models returned by your database need to have an unique id.

Routes

This module is built to work with sails.js blueprints routes using sails-rest-api conventions. It differentiate singular and plural model name : findUser !== findUsers IMPORTANT ! As sails.js, this module uses pluralize module which pluralize words grammaticaly.

some exemples : channel -> channels person -> people coach -> coaches

By default, all your routes will be pluralized, Person model will have the following :

state : person - a single person people - all your "persons"

actions : findPerson -> will hit GET /people/:id findPeople -> will hit GET /people

You can unpluralize your urls by setting it in the config

Authentication

redux-crud-async uses a Bearer Token to authenticate requests. It is store in window.localStorage. Every request which need authentication is sent with the token in the header following this convention :

Token is set in Authorization header as :

// Config sent to axios or socket.io
{
    headers : {
      Authorization : 'Bearer '+ JWT_Token_from_localStorage
    }
}

Socket

We use the io.socket.request to communicate to the server. Make sure that your server can use it if you don't use sails.js on server side.


##Configuration

Config file

| Name | Type | Default | Description | |:--- |:--- |:--- |:--- | | host | String | null | Your API host - must be defined | | prefix | String | null | A prefix for all your routes. Don't add the slash / on the prefix it will be automatically added.| | pluralizeModels | Boolean | true | Use pluralized model names in url. This has no affect on action names. | | socket | Boolean | false | Use socket.io for actions | | localStorageName | String | "JWT" | The key for retrieving your JWT Token from window.localStorage | | headerContent | String | "Bearer {{JWT}}" | The format of your header content The format is affected by localStorageName | | headerFormat | String | "Authorization" | The format of your header authorization key | | apiSpecs | Object | null | Routes where you want to use the JWT_Token | | responseSchemas | Object | {http: {success : 'data', error : 'data'}, socket : {success : null, error : null}} | schemas of your API's responses. Where the data can be found in your response object

The format of headerContent is affected by localStorageName if you change the default value

{
  localStorageName : 'myJWT',
  headerContent : 'MyContent {{myJWT}}'
}

For apiSpecs you just have to set the unpluralized modelName or primarymodelAssociatedmodels with an auth property inside which contains an array of actions to authenticate. Just follow conventions given above.

{
  host            : 'http://your-api-host',
  prefix          : 'my-prefix',
  pluralizeModels : false,
  socket          : true,
  localStorageName: 'MyJWT',
  headerContent   : 'AuthBearer {{MyJWT}}',
  headerFormat    : 'AuthBearerHeaderKey'
  apiSpecs : {

    coach : {
      // All the following actions will be beared with a JWT
      auth : ['findCoaches', 'createCoach', 'updateCoach']
    },

    coachComments : {
      auth : ['addCommentToCoach', 'removeCommentFromCoach']
    }
  }
}

#### Results findPerson -> will hit GET http://your-api-host/my-prefix/people/:id findPeople -> will hit GET http://your-api-host/my-prefix/people

With pluralizeModels : false findPerson -> will hit GET http://your-api-host/my-prefix/person/:id findPeople -> will hit GET http://your-api-host/my-prefix/person


Actions

Names

There is a maximum of 11 actions for a given model which will be automatically understood by reducers. 3 status actions are dispatched for every redux-crud-async action : START, SUCCESS and ERROR. They are automatically understood by reducers. eg. primary model = channel, associated model = tag

3 primary

| actionName | url | param | state | state Type | |:--- |:--- |:--- |:--- |:--- | | findChannel | GET channels/:id | String | channel | Object | | findChannels | GET channels?request | String | channels | [Object] | | createChannel | POST channels | Object OR FormData | channel | Object | | updateChannel | PUT channels | Object| channel | Object | | destroyChannel | DELETE channels | Object| channel | Object |

You can submit a FormData to create but the FormData is transmitted as is and model will not be appended to the state. If you need the model to be appended to the state, use a javascript object instead of a FormData. FormData can be used to send specific CRUD actions like uploading an image

3 association

| actionName | url | parameters | state | state Type | Comment | |:--- |:--- |:--- |:--- |:--- |:--- | | findChannelTags | GET channels/:channelId/tags/:tagId? | String, String | channelTags | [Object] | | | addTagToChannel | POST channels/:channelId/tags/:tagId? |String, String OR Object | channelTag | Object | if no tag id is set you must give an object to this function | | createChannel | POST channels | String, String | channelTag | Object | |

#### Additionnal actions

An additionnal action exists which empties reducers. Dispatch manually this action to empty your reducers.

{
  type : 'EMPTY_CHANNEL'
}
{
  type : 'EMPTY_CHANNELS'
}
{
  type : 'EMPTY_PRIMARY_ASSOCIATED_MODELS'
}

Have a look in primaryActionGenerator and associationActionGenerator and Actions Details for more precision about dispatched actions.

States (Reducers)

Reducers return the following states usable in your components

| state | type | |:--- |:--- | | channel | Object | | isFindingChannel | Boolean | | channels | [Object] | | isFindingChannels | Boolean | | channelTags | [Object] | | isFindingChannelTags | Boolean |

See reducers :


## TODO

  • make API endpoints editables
  • add cache for get requests
  • cache timeout by route
  • remove arrow functions in tests
  • comment code
  • find a way to test FormData in createModel
  • add single actions (signup, signin)
  • add coverage
  • move associated record uuid generation from associationActions dispatch to reducer
  • state immutability
  • add tests for caching
  • add some headers tests

## Change Log

0.7.0
  • removed second parameter from update action
0.6.3
  • update and delete primary actions
  • fix bug when building with webpack - io was undefined
  • fix silly bugs and add tests for them
0.5.0
  • API expectation editables
0.4.0
  • add socket.io support through the window.io variable
  • more tests
  • rewrite of the utils/xhr/* module
  • doc changes
  • added EMPTY_CHANNELS action in reducers