Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arraySplice supports unlimited number of items #4522

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/__tests__/actions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ describe('actions', () => {
removeNum: 0
},

payload: 'foo'
payload: ['foo']
})

expect(isFSA(arraySplice('myForm', 'myField', 2, 0, 'foo'))).toBe(true)
Expand All @@ -239,9 +239,7 @@ describe('actions', () => {
removeNum: 2
},

payload: {
foo: 'bar'
}
payload: [{ foo: 'bar' }]
})

expect(isFSA(arraySplice('myForm', 'myField', 3, 2, { foo: 'bar' }))).toBe(
Expand All @@ -258,7 +256,7 @@ describe('actions', () => {
field: 'myField'
},

payload: 'foo'
payload: ['foo']
})

expect(isFSA(arrayUnshift('myForm', 'myField', 'foo'))).toBe(true)
Expand Down
21 changes: 13 additions & 8 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ const arraySplice: ArraySplice = (
field: string,
index: number,
removeNum: number,
value: any
...value: any
): ArraySpliceAction => {
const action: ArraySpliceAction = {
type: ARRAY_SPLICE,
meta: { form, field, index, removeNum }
}
if (value !== undefined) {
if (Array.isArray(value) && value.length > 0) {
action.payload = value
}
return action
Expand All @@ -206,12 +206,17 @@ const arraySwap: ArraySwap = (
const arrayUnshift: ArrayUnshift = (
form: string,
field: string,
value: any
): ArrayUnshiftAction => ({
type: ARRAY_UNSHIFT,
meta: { form, field },
payload: value
})
...value: any
): ArrayUnshiftAction => {
const action: ArrayUnshiftAction = {
type: ARRAY_UNSHIFT,
meta: { form, field }
}
if (Array.isArray(value) && value.length > 0) {
action.payload = value
}
return action
}

const autofill: Autofill = (
form: string,
Expand Down
14 changes: 10 additions & 4 deletions src/createReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,12 @@ function createReducer<M, L>(structure: Structure<M, L>) {
: state
}
const rootKeys = ['values', 'fields', 'submitErrors', 'asyncErrors']
const arraySplice = (state, field, index, removeNum, value) => {
const arraySplice = (state, field, index, removeNum, ...value) => {
let result = state
const nonValuesValue = value != null ? empty : undefined
const realvalue = value.length == 0 ? undefined : value
const nonValuesValue = Array.isArray(realvalue)
? value.map(value => (value != null ? empty : undefined))
: undefined
result = doSplice(result, 'values', field, index, removeNum, value, true)
result = doSplice(result, 'fields', field, index, removeNum, nonValuesValue)
result = doPlainSplice(
Expand Down Expand Up @@ -228,7 +231,9 @@ function createReducer<M, L>(structure: Structure<M, L>) {
payload
}
) {
return arraySplice(state, field, index, removeNum, payload)
if (payload === undefined)
return arraySplice(state, field, index, removeNum)
else return arraySplice(state, field, index, removeNum, ...payload)
},
[ARRAY_SWAP](
state,
Expand All @@ -254,7 +259,8 @@ function createReducer<M, L>(structure: Structure<M, L>) {
payload
}
) {
return arraySplice(state, field, 0, 0, payload)
if (payload === undefined) return arraySplice(state, field, 0, 0, payload)
else return arraySplice(state, field, 0, 0, ...payload)
},
[AUTOFILL](
state,
Expand Down
13 changes: 7 additions & 6 deletions src/structure/immutable/__tests__/splice.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,33 @@ import splice from '../splice'

describe('structure.immutable.splice', () => {
const testInsertWithValue = value => {
const argval = value === undefined ? value : [value]
it('should insert even when initial array is undefined', () => {
const structure = splice(undefined, 2, 0, value)
const structure = splice(undefined, 2, 0, argval)
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(fromJS([undefined, undefined, value]))
})

it('should insert at start', () => {
const structure = splice(fromJS(['b', 'c', 'd']), 0, 0, value)
const structure = splice(fromJS(['b', 'c', 'd']), 0, 0, argval)
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(fromJS([value, 'b', 'c', 'd']))
})

it('should insert at end', () => {
const structure = splice(fromJS(['a', 'b', 'c']), 3, 0, value)
const structure = splice(fromJS(['a', 'b', 'c']), 3, 0, argval)
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(fromJS(['a', 'b', 'c', value]))
})

it('should insert in middle', () => {
const structure = splice(fromJS(['a', 'b', 'd']), 2, 0, value)
const structure = splice(fromJS(['a', 'b', 'd']), 2, 0, argval)
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(fromJS(['a', 'b', value, 'd']))
})

it('should insert in out of range', () => {
const structure = splice(fromJS(['a', 'b', 'c']), 5, 0, value)
const structure = splice(fromJS(['a', 'b', 'c']), 5, 0, argval)
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(
fromJS(['a', 'b', 'c', undefined, undefined, value])
Expand All @@ -52,7 +53,7 @@ describe('structure.immutable.splice', () => {
})

it('should remove in the middle then insert in that position', () => {
const structure = splice(fromJS(['a', 'b', 'c', 'd']), 1, 1, 'e')
const structure = splice(fromJS(['a', 'b', 'c', 'd']), 1, 1, ['e'])
expect(structure).toBeInstanceOf(List)
expect(structure).toEqual(fromJS(['a', 'e', 'c', 'd']))
})
Expand Down
11 changes: 8 additions & 3 deletions src/structure/immutable/splice.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export default (
.splice(index, 0, true) // placeholder
.set(index, undefined)
}
if (value != null) {
return list.splice(index, removeNum, value) // removing and adding
if (Array.isArray(value)) {
return list.splice(index, removeNum, ...value) // removing and adding
} else {
return list.splice(index, removeNum) // removing
}
Expand All @@ -29,5 +29,10 @@ export default (
return list
}
// trying to add outside of range: just set value
return list.set(index, value)
if (Array.isArray(value)) {
value.forEach(value => (list = list.set(index++, value)))
} else {
list = list.set(index, value)
}
return list
}
13 changes: 7 additions & 6 deletions src/structure/plain/__tests__/splice.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import splice from '../splice'

describe('structure.plain.splice', () => {
const testInsertWithValue = value => {
const argval = value === undefined ? value : [value]
it('should insert even when initial array is undefined', () => {
// really goes to index 0
expect(splice(undefined, 2, 0, value)).toEqual([
expect(splice(undefined, 2, 0, argval)).toEqual([
undefined,
undefined,
value
])
})

it(`should insert ${value} at start`, () => {
expect(splice(['b', 'c', 'd'], 0, 0, value)).toEqual([
expect(splice(['b', 'c', 'd'], 0, 0, argval)).toEqual([
value,
'b',
'c',
Expand All @@ -21,7 +22,7 @@ describe('structure.plain.splice', () => {
})

it(`should insert ${value} at end`, () => {
expect(splice(['a', 'b', 'c'], 3, 0, value)).toEqual([
expect(splice(['a', 'b', 'c'], 3, 0, argval)).toEqual([
'a',
'b',
'c',
Expand All @@ -30,7 +31,7 @@ describe('structure.plain.splice', () => {
})

it(`should insert ${value} in middle`, () => {
expect(splice(['a', 'b', 'd'], 2, 0, value)).toEqual([
expect(splice(['a', 'b', 'd'], 2, 0, argval)).toEqual([
'a',
'b',
value,
Expand All @@ -39,7 +40,7 @@ describe('structure.plain.splice', () => {
})

it(`should insert ${value} when index is out of range`, () => {
expect(splice(['a', 'b', 'c'], 5, 0, value)).toEqual([
expect(splice(['a', 'b', 'c'], 5, 0, argval)).toEqual([
'a',
'b',
'c',
Expand All @@ -62,7 +63,7 @@ describe('structure.plain.splice', () => {
})

it('should remove in the middle then insert in that position', () => {
expect(splice(['a', 'b', 'c', 'd'], 1, 1, 'e')).toEqual([
expect(splice(['a', 'b', 'c', 'd'], 1, 1, ['e'])).toEqual([
'a',
'e',
'c',
Expand Down
10 changes: 7 additions & 3 deletions src/structure/plain/splice.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ const splice = (
copy[index] = undefined // set to undefined
return copy
}
if (value != null) {
if (Array.isArray(value)) {
const copy = [...array]
copy.splice(index, removeNum, value) // removing and adding
copy.splice(index, removeNum, ...value) // removing and adding
return copy
}
const copy = [...array]
Expand All @@ -30,7 +30,11 @@ const splice = (
}
// trying to add outside of range: just set value
const copy = [...array]
copy[index] = value
if (Array.isArray(value)) {
value.forEach(value => (copy[index++] = value))
} else {
copy[index] = value
}
return copy
}

Expand Down