Skip to content

AlexHenkel/redux-observable-crud

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

Provides a redux-observer CRUD functions generator, to have a nice DRY code on observer files. This will increase scalability and maintainability as there's only one file to maintain.

Observables here are used in the following way:

  1. Listen to a redux request action.
  2. If the action is intended to call API, verify if matching info already exists and fire a success redux action.
  3. Call API
  4. If API call is success, fire a success redux action with transformed data. Else, fire a failure redux action with error

More about redux-observable

It supports five major CRUD actions, and 3 subactions to sync data with state and simulate hot refreshing:

  • Get: Action to get all valid records. Ex. GET: api.dev/collection

  • Get One: Action to get one record by id. Ex. GET: api.dev/collection/{id}

  • Create: Action to add a record to collection. Ex. POST: api.dev/collection

  • Update: Action to update a record by id. Ex. POST: api.dev/collection/{id}

  • Remove: Action to update a record by id. Ex. POST: api.dev/collection/{id}

  • Create Success: Action to update existing data on create success

  • Update Success: Action to update existing data on update success

  • Remove Success: Action to update existing data on remove success

Note: This library is optimized to be used along reduxsauce-crud to handle CRUD actions as well with Redux

Installation

yarn add https://github.com/alexhenkel/redux-observable-crud.git

Usage Example

src/Data/Observables/NetworksObservable.js

import createCRUDObservable from 'reduxobserver-crudsauce'
import { combineEpics } from 'redux-observable'
import { NetworksRedux } from '../Redux/NetworksRedux'
import { CountriesRedux } from '../Redux/CountriesRedux'

const networksCrudObservable = createCRUDObservable({
  mainRedux: NetworksRedux,
  reduxPath: 'networks',
  create: {
    onSuccessActions: [
      {
        redux: CountriesRedux,
        filter: (country, item) => item.country.id === country.id,
      },
    ],
  },
  update: {
    onSuccessActions: [
      { redux: CountriesRedux },
    ],
  },
  remove: {
    onSuccessActions: [
      { redux: CountriesRedux },
    ],
  },
  dataHandlers: {
    getOne: response => response.data.data.name,
  }
})

// For testing
export const networksObservers = Object.assign({}, networksCrudObservable.observers, {})

export const networksEpic = combineEpics(
  networksCrudObservable.epic,
)

In this example we are creatinig observables for networks collection and syncing with countries

The function returns an object of observables for testing and epic, which can be combined to other epics to setup Redux Middleware src/Data/Observables/index.js

import { combineEpics, createEpicMiddleware } from 'redux-observable'
import Api from '../Api'
import { networksEpic } from './NetworksObservable'

const rootEpic = combineEpics(
  networksEpic,
)

export default createEpicMiddleware(rootEpic, {
  dependencies: { Api },
})

Options

mainRedux (Required) This is the Redux file of the collection. This should be generated by reduxsauce-polymer.

reduxPath (Required) Name of the state path declared on redux state. Generally, it should be the name of the collection in lowercase plural.

modifier (Optional) Function to manipulate API result. It's used to calculate and add fields based on other fields. If it's not provided, data will not be transformed.

create.onSuccessActions / update.onSuccessActions / remove.onSuccessActions (Optional) This will be an array of Redux options to sync data in other redux that may contain same information.

onSuccessActions.redux (Required if past option is present) Redux file of the collection that needs to be synced

onSuccessActions.pathToUpdate (Optional) As default, same reduxPath is used to look into provided redux file, but this can be override with this option.

create.onSuccessActions.filter (Optional) Filter to decide if new object should be included to other Redux file. For example, Country is a collection that contains networks; when a network is created, we should verify that network belongs to country in order to add new item.

dataHandlers (Optional) Callback functions to override the default data handler for every CRUD Action. If some is not present, the default function will be used.

Default: response => response.data.data

Usage:

dataHandlers = {
	get: response => response,
	getOne: response => response,
	create: response => response,
	update: response => response,
	remove: response => response,
}

API

This library is optimized to work with Axios and in the following format to match all the CRUD Actions

import { create } from 'axios'

const baseURL = 'http://api.demo.dev/'

const api = create({
  baseURL,
  timeout: 10000,
})

const getNetworks = () => api.get('backend/networks')
const getNetwork = id => api.get(`backend/networks/${id}`)
const updateNetwork = (id, data) => api.patch(`backend/networks/${id}`, data)
const createNetwork = data => api.post('backend/networks', data)
const removeNetwork = id => api.delete(`backend/networks/${id}`)

/**
 * Key should match `reduxPath` in Observable file, and then each key
 * the following keys should be included: `get`, `getOne`, `create`, 
 * `update`
 */
export default {
  networks: {
    get: getNetworks,
    getOne: getNetwork,        
    create: createNetwork,
    update: updateNetwork,
    remove: removeNetwork,
  },
}

About

Add CRUD features for Redux-Observable architecture

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published