Skip to content

Commit

Permalink
Merge dffcea9 into 70c8d90
Browse files Browse the repository at this point in the history
  • Loading branch information
richardcrng committed Apr 18, 2019
2 parents 70c8d90 + dffcea9 commit d473f58
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 2 deletions.
40 changes: 39 additions & 1 deletion docs/create/asObject/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,49 @@ If the leaf was initialised with [plain object](https://lodash.com/docs/4.17.11#
If the current `leafState` is *not* a plain object, then it is first coerced into a plain object via lodash's [`_.toPlainObject(leafState)`](https://lodash.com/docs/4.17.11#toPlainObject) method, before the state is updated according to the action dispatched.

### Action creators
- [`create.asObject.assign(...sources)`](#createasobjectassignsources)
- [`create.asObject.set(path, value)`](#createasobjectsetpath-value)

[Back to all `create` action creators](https://github.com/richardcrng/redux-leaves/tree/master/docs/create#action-creators)

## `create.asObject.assign(...sources)`
**alias: `create.assign(...sources)`** *(when `initialLeafState` is a [plain object](https://lodash.com/docs/4.17.11#toPlainObject))*

Returns an object that, *when dispatched to a store created with the original state tree*, updates the copies all properties from `sources` into the leaf's state.

(This is essentially a convenience wrapper on top of the vanilla JavaScript [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).)

### Parameters
- `sources` *(...objects)*: the path of the property to set

### Returns
`action` *(object)*: an object to dispatch to the store

### Example
```js
import { createStore } from 'redux'
import reduxLeaves from 'reduxLeaves'

const initialState = {
foo: { props: true }
}

const [reducer, actions] = reduxLeaves(initialState)
const store = createStore(reducer)
```
```js
store.dispatch(actions.foo.create.asObject.assign({ string: 'foo' }))
console.log(store.getState().foo) // { props: true, string: 'foo' }
```
```js
store.dispatch(actions.ar.create.asObject.assign({ props: false }))
console.log(store.getState().foo) // { props: false, string: 'foo' }
```
Back to:
* [`create.asObject` action creators](#action-creators)
* [all `create` action creators](https://github.com/richardcrng/redux-leaves/tree/master/docs/create#action-creators)


## `create.asObject.set(path, value)`
**alias: `create.set(path, value)`** *(when `initialLeafState` is a [plain object](https://lodash.com/docs/4.17.11#toPlainObject))*

Expand All @@ -29,7 +68,6 @@ Returns an object that, *when dispatched to a store created with the original st
import { createStore } from 'redux'
import reduxLeaves from 'reduxLeaves'

// note: object leaves have to be initialised with empty objects
const initialState = {
foo: {}
bar: { props: true }
Expand Down
39 changes: 39 additions & 0 deletions docs/create/asObject/assign.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

describe("leaf.create.assign(...sources): returns an action that, when dispatched, updates the leaf's state by non-mutatively copying over properties from the sources", () => {

describe("Documentation example 1", () => {

describe("GIVEN initial state, reducer, actions and store as in example", () => {
const initialState = {
foo: { props: true }
}

const [reducer, actions] = reduxLeaves(initialState)
let store

beforeEach(() => store = createStore(reducer))

test("THEN store initialises with initialState", () => {
expect(store.getState()).toEqual(initialState)
})

describe("WHEN we dispatch actions.foo.create.asObject.assign({ string: 'foo' })", () => {
beforeEach(() => {
store.dispatch(actions.foo.create.asObject.assign({ string: 'foo' }))
})

test("THEN store state.foo updates to { props: true, string: 'foo' }", () => {
expect(store.getState()).toEqual({
foo: { props: true, string: 'foo' }
})
})

})
})


})
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redux-leaves",
"version": "0.2.5",
"version": "0.2.6",
"license": "MIT",
"author": {
"name": "Richard Ng",
Expand Down
1 change: 1 addition & 0 deletions src/actions/atomic/atomicActions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const atomicActions = {
APPLY: "APPLY", // updates slice of state by applying payload (function) to it
ASSIGN: "ASSIGN",
CLEAR: "CLEAR", // updates slice of state to null
CONCAT: "CONCAT", // concats payload to state
DROP: "DROP", // non-mutative drop of n elements from array's beginning
Expand Down
3 changes: 3 additions & 0 deletions src/actions/for/object/forObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ export const forObject = (pathToLeafOrBranch = []) => {
{ condition: conditions.OBJECT }
)

const assign = (...sources) => actionTemplate(atomicActions.ASSIGN, sources)

const set = (path, value) => actionTemplate(atomicActions.SET, { path, value })

return {
assign,
set
}
}
6 changes: 6 additions & 0 deletions src/leafReducer/object/leafReducerObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ import { updateState } from '../..';
export const leafReducerObject = (leafState, { modifier, payload }) => {
const state = _.isPlainObject(leafState) ? leafState : _.toPlainObject(leafState)
switch (modifier) {
case atomicActions.ASSIGN: return assign(state, payload)
case atomicActions.SET: return set(state, payload)
default: return state
}
}

const assign = (state, sources) => Object.assign(
{ ...state }, // stop immer complaining
...sources
)

const set = (state, { path, value }) => updateState(state, path, value)

0 comments on commit d473f58

Please sign in to comment.