Created
April 21, 2017 04:32
-
-
Save pentaphobe/3ec67a51edb9c6edcad9351f390707d5 to your computer and use it in GitHub Desktop.
Alternate updateIn() for ImmutableJS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Convenience function for deep updates including searches in the path | |
*/ | |
export default function updateIn(immutableType, pathArray, updater) { | |
// pathArray can contain matcher functions | |
let failed = false; | |
let parsedPath = []; | |
pathArray.every( (pathEl, idx) => { | |
if (typeof pathEl !== 'function' && typeof pathEl !== 'object') { | |
parsedPath.push(pathEl); | |
return true; | |
} | |
let items = immutableType.getIn(parsedPath); | |
let fn; | |
// if it's an object, then our match function requires all keyed entries match | |
if (typeof pathEl === 'object') { | |
fn = function (list) { | |
let keys = Object.keys(pathEl); | |
return list.findIndex( item => { | |
for (let key of keys) { | |
if (item.get(key) !== pathEl[key]) return false; | |
} | |
return true; | |
}); | |
} | |
} else { | |
fn = function (list) { | |
return list.findIndex( pathEl ); | |
}; | |
} | |
let index = fn(items); | |
// TODO: this isn't robust enough | |
if (index === -1) { | |
failed = true; | |
return false; | |
} | |
parsedPath.push( index ); | |
return true; | |
}); | |
if (failed) { | |
// TODO: is this how we want to operate? | |
return undefined; | |
} | |
return immutableType.updateIn(parsedPath, function (item) { | |
return updater(item, immutableType); | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Immutable from 'immutable'; | |
import updateIn from './updateIn'; | |
/**************************************************************************************** | |
* | |
* Example as per https://gist.github.com/kastermester/8c40b35843a38ea7ef5d | |
* | |
****************************************************************************************/ | |
let state = Immutable.fromJS({ | |
product_preview: { | |
product_type: '', | |
media_items: [ | |
{id: 0, url: 'my_url'}, | |
{id: 1, url: 'my_url'}, | |
{id: 2, url: 'my_url'} | |
], | |
}, | |
}); | |
/* | |
// Lastly, using `updateIn` | |
var newState = state.updateIn(['product_preview', 'media_items'], function(list){ | |
var idx = list.findIndex(function(item){ | |
return item.get('id') === 1; | |
}); | |
return list.setIn([idx, 'url'], 'my_new_url'); | |
}); | |
*/ | |
var newState = updateIn(state, ['product_preview', 'media_items', {id:1}], function (item, list) { | |
return item.set('url', 'new_url'); | |
}); | |
// or alternatively: | |
var newState2 = updateIn(state, ['product_preview', 'media_items', item => item.get('id') === 1], function (item, list) { | |
return item.set('url', 'new_url'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment