Skip to content

Instantly share code, notes, and snippets.

@crshmk
Last active October 23, 2020 19:38
Show Gist options
  • Save crshmk/3c32bc48a3f0aa86150400dd1cf444ee to your computer and use it in GitHub Desktop.
Save crshmk/3c32bc48a3f0aa86150400dd1cf444ee to your computer and use it in GitHub Desktop.
updating a collection
import { always, map, propEq, when } from 'ramda'
let replaceItem = (item, list) =>
map(when( propEq('id', item.id) , always(item)), list)
export default replaceItem
import replaceItem from './replaceItem'
describe('replaceItem', function() {
test('replaces an item in a collection in place by id', function() {
let state = [
{id: 1, name: 'one'},
{id: 2, name: 'two'},
{id: 3, name: 'three'}
]
let update = {id: 2, color: 'green' }
let expected = [
{id: 1, name: 'one'},
{id: 2, color: 'green'},
{id: 3, name: 'three'}
]
expect(replaceItem(update, state)).toMatchObject(expected)
})
})
import { eqProps, ifElse, map, mergeDeepLeft } from 'ramda'
let idsEq = eqProps('id')
let identity = x => x
let updateItem = update =>
map(ifElse(
idsEq(update),
mergeDeepLeft(update),
identity)
)
export default updateItem
import updateItem from './updateItem'
describe('updateItem', function() {
test('finds an item in a collection by id and updates relevant properties', function() {
let state = [
{ id: 1, name: 'one', items: []},
{ id: 2, name: 'two',items: []},
{ id: 3, name: 'three', items: []}
]
let updatedItem = {id: 2, name: 'new name', items: [{one: 1}]}
let expected = [
{ id: 1, name: 'one', items: []},
{ id: 2, name: 'two', name: 'new name', items: [{one: 1}]},
{ id: 3, name: 'three', items: []}
]
let update = updateItem(updatedItem)
let updatedCollection = update(state)
expect(updatedCollection).toMatchObject(expected)
})
test('adds a property to a collection item', function() {
let state = [
{ id: 1, items: []},
{ id: 2, items: []},
{ id: 3, items: []}
]
let updatedItem = {id: 2, newProp: 42}
let expected = [
{ id: 1, items: []},
{ id: 2, items: [], newProp: 42},
{ id: 3, items: []}
]
let update = updateItem(updatedItem)
let updatedCollection = update(state)
expect(updatedCollection).toMatchObject(expected)
})
})
import { curry, eqProps, map} from 'ramda'
let idsEq = eqProps('id')
export let updateItem2 = curry((updated, collection) =>
map(item => idsEq(item, updated) ? updated : item, collection)
)
@crshmk
Copy link
Author

crshmk commented Oct 23, 2020

i want to just update a collection by declaring the update and the collection. the above utils allow you to throw an object at a collection and either replace it or update its props by matching the id of the update with an id in a collection item.

@crshmk
Copy link
Author

crshmk commented Oct 23, 2020

// ensure the update has an id prop
let update = updateItem({id: 42, updatedProp: 43})
let collection = update(this.state.collection)
this.setState({ collection })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment