Skip to content

Instantly share code, notes, and snippets.

@pentaphobe
Created April 21, 2017 04:32
Show Gist options
  • Save pentaphobe/3ec67a51edb9c6edcad9351f390707d5 to your computer and use it in GitHub Desktop.
Save pentaphobe/3ec67a51edb9c6edcad9351f390707d5 to your computer and use it in GitHub Desktop.
Alternate updateIn() for ImmutableJS
/**
* 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);
});
}
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