Code Monkey home page Code Monkey logo

immutability-helper's People

Contributors

adelgado avatar andreiglingeanu avatar bwells avatar caydenberg avatar charlax avatar connormiha avatar danielruf avatar epicfaace avatar fabb avatar fatfisz avatar georapbox avatar gnapse avatar hustcc avatar jedmao avatar jednano avatar jmz7v avatar jpkleemans avatar kolodny avatar michaeldeboey avatar pawsong avatar pladaria avatar remko avatar roryokane avatar seansfkelley avatar semicoleon avatar snarehanger avatar stefk avatar technikfischer avatar vladtsf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

immutability-helper's Issues

Trying to update state

Hello,

I have a simple piece of code as shown below:

for (var i = this.state.structure.length - 1; i >= 0; i--) {
    this.state.structure[i].active = false
    if( this.state.structure[i].id == id ){
        this.state.structure[i].active = true
    }
}
this.forceUpdate()

This code works fine and the state is updated as required. But when I try to do the same using immutability helper then it does not work. Seems like it runs only for the first time as all values are set to false.

for (var i = this.state.structure.length - 1; i >= 0; i--) {
    this.setState({
        structure: update(this.state.structure, {[i]: {active: {$set: false}}})
    })
    if( this.state.structure[i].id == id ){
        this.setState({
            structure: update(this.state.structure, {[i]: {active: {$set: true}}})
        })
    }
}

What I am doing wrong here?

How to set currently-undefined nested structure?

Not really an issue, but hoping for a best practice, perhaps.

> update({}, {a: {b: {c: {$set: true}}}})
TypeError: Cannot read property 'b' of undefined
    at update (/Users/jordan/Code/kiddom/teacherdashboard/node_modules/immutability-helper/index.js:65:44)
    at update (/Users/jordan/Code/kiddom/teacherdashboard/node_modules/immutability-helper/index.js:65:31)
    at repl:1:1
    at REPLServer.defaultEval (repl.js:248:27)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:412:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:210:10)

My target doesn't have all the keys. Is there a clean way to deep-set the structure from source?

$merge command still returns copy even if no modifications made

I think that the $merge command should be a bit more intelligent if the merges would not affect the state.
So if I merge an empty object, or an object with the same values it should not clone but rather return the original. For example the following results should return the original:

let original = { a: { b: 'c' } };
let result1 = update(original, { a: { $merge: {} } } );
let result2 = update(original, { a: { $merge: { b: 'c' } } } );

I have published a running example in runkit:
https://runkit.com/markwhitfeld/immutability-helper-merge-example/1.0.0

In the second half you of this runkit sample you will see that I replace the $merge command with a new implementation that would give the desired behaviour by using the $set operator for each of the merged properties.

What do you think?

Use the doc from React repo

I think it would be great if the doc was moved here because we plan to eventually remove it.
The new functionality could be described together with the old one.

It seems `$merge` doesn't really work.

Like title described, consider about this case:

const state = {
  a: 1,
  b: {
    c: 2
  }
}

const tmp = {
  b: {
    d: 3
  }
}

update(state, {
  $merge: tmp
})

Gave the result:

 {
  a: 1,
  b: {
    d: 2
  }
}

Which we lost the original property c: 2.

Nested $merge does not seem to work

Hi,

maybe I'm missing something, but I'm not able to run this:

import update from 'immutability-helper';

let state = {
	isValid: null,
	isVisible: false,

	set: {
		isValid: null,
		isVisible: false,

		distance: {
			isValid: null,
			isVisible: false
		},
		hours: {
			isValid: null,
			isVisible: false
		}
	}
};

update(state, {
	set: {
		$merge: {
			isVisible: activity !== null && activity !== '',

			distance: {
				$merge: {
					isVisible: activity === 'bike' || activity === 'run'
				}
			},
			hours: {
				$merge: {
					isVisible: activity === 'other'
				}
			}
		}
	}
)

The output of update method is:
snimek z 2017-02-07 08-58-38

So the nested merge does not parse. Is this a bug, or a feature?

Thank you,
dakur

Please add a license

It would be great to add an explicit license statement to this project to clarify terms of its usage.

This project became an officially recommended replacement for react-addon-update which has been deprecated. However in order to use this project, one must be sure about its terms of usage.

Feature request: add support for ES6 Sets

I'd love to see $add/$delete being added to the library.

Use case example is a React table component which has state.expandedRows: Set<string> where each item of the set represents a row which has some expanded extra information. Using a Set is much nicer to read than abusing $set/$unset for this purpose (which I'll try right now as workaround).

References not always preserved?

Here's an example of a potentially incorrect behaviour:

const orig = {
  a: [1, 2],
  b: [3, 4],
  c: [5, 6],
}

const result = update(orig, {
  $set: {
    b: [7, 8],
  }
});

console.log(
  orig.a === result.a,
  orig.b === result.b,
  orig.c === result.c,
);

Expected: true, false, true, got false, false, false.

I'd expect the above example to give the same result as the native spread operator:

const orig = {
  a: [1, 2],
  b: [3, 4],
  c: [5, 6],
}

const result = {
  ...orig,
  b: [7, 8],
};

console.log(
  orig.a === result.a,
  orig.b === result.b,
  orig.c === result.c,
);

This gives true, false, true, as expected.

The issue may be related to #1.

Arrays are not copied properly - keys are lost

Consider:

a = { items: [ { name: 'Superman', strength: 1000 }, { name: 'Jim', strength: 2 } ]
a.items.top = 0
a
// =>
// { items: 
//    [ { name: 'Superman', strength: 1000 },
//      { name: 'Jim', strength: 2 },
//      top: 0 ] }
c
=>
 { items: [
    { name: "Superman", strength: 1000 },
    { name: "Jim", strength: 2 }
  ] 
}
cmd = { items: { 1: { strength: { $set: 3 } } } }
b = update(a, cmd)
b
// =>
// { items: 
//    [ { name: 'Superman', strength: 1000 },
//      { name: 'Jim', strength: 3 } ] }

Notice the "top" key was lost. The culprit is (I believe) line 22 where it should be:

function copy(object) {
  if (object instanceof Array) {
-     return object.slice();
+     return assign(object.constructor(), object)
  } else if (object && typeof object === 'object') {
    var prototype = object.constructor && object.constructor.prototype

Keys should not be lost.

a new api to update an object

we can basically expose another API which takes in an array and the action somewhat like this

update (object, pathArray/path, method, value)

and then do the same thing like the current API does

HowTo: Delete an object using the objects id?

So, and as shown in the attached image, I'm attempting to delete a comment object, from an array of objects, using the comments id. What's the best approach to do this?

I'm currently deleting the object using its index, but this has led to out-of-sync issues (incorrect items being deleted):

this.currentState = update(previousState, {allPostses: {[postIndexID]: {comments: {$splice:[[[this.MyVars.indexVal],1]]}}}});
return Object.assign({}, previousState, {
  allPostses: this.currentState.allPostses
})
;```

![delete_comments](https://cloud.githubusercontent.com/assets/15969262/25557810/70bf5094-2d11-11e7-85da-a6d7ec69b31f.jpg)


Swapping values of a nested array

I am trying to swap values of an array based on index. Below is scaled down version of my code.
The index values will be dynamic.

const s = [ [ 1, 2, 3, 4 ] ]

const v1= s[ 0 ][ 1 ];
const v2 = s[ 0 ][ 2 ];

const s1 = update( s, {
    0: { 1: { $set: v2 } },
    0: { 2: { $set: v1 } }
} );

console.log(s1); //[ [ 1, 2, 2, 4 ] ]

Swapping between two different arrays works perfectly fine

const s = [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ] ]

const v1= s[ 0 ][ 1 ];
const v2 = s[ 1 ][ 2 ];

const s1 = update( s, {
    0: { 1: { $set: v2 } },
    1: { 2: { $set: v1 } }
} );

console.log(s1); //[ [ 1, 7, 3, 4 ], [ 5, 6, 2, 8 ] ]

I am not sure if this is an issue or something wrong with my code.

Support for symbols missing?

I was trying to use update with apollo-client. I see support for symbols was added in 2.1.0 but its still not working for me.

Original data:
Object {goal: Object, Symbol(id): "ROOT_QUERY"}

Update code

          const updatedData = update(data,{
            "goal": {
              "baseSips": {"$apply":baseSips => {
                if (baseSips) {
                  return update(baseSips[0],{"$set":[baseSip]});
                }
                return update([],{"$push":[baseSip]});
              }}
            }
          }
        );

Updated data
Object {goal: Object}

I am trying on version 2.2.0

$unset doesn't completely remove a property from the object

It would be great if $unset completely removed a property of the object. Right now it just set it to undefined.
I have messagesById collection and map its keys to components.

const ids = Object.keys(messagesById)

ids.map(id => 
  <Message
    text={ messagesById[ id ].text }
  />
)

It falls down after I use { $unset: ['asdf_23fsd', 'asdf244s_3'] } because collection looks like this

{
 asdf_23fsd: undefined,
 asdf244s_3: undefined,
}

Feature Request: Add path notation.

Without a path notation it is not actually possible to edit an update spec object with an update spec since it cannot distinguish a key from an operation. Adding path notation also has the advantage that it would also provide dot notation as requested in #17.

The method to disambiguate unusual keys is to use the normal bracket notation (with escaping for at least the close bracket) optionally with quote support. With this the operation doesn’t actually need any special handling since it must always be the last element in any path.

This then gives the following:

const newData = updatePath(myData, {
  "x.y.z.$set": 7,
  "a.b.$push": [9]
});
const newCollection = updatePath(collection, { "2.a.$splice": [[1, 1, 13, 14]]});
const newPathed = updatePath(pathed, {
  "[path.with.dots][next.part].$set": true, // sets pathed["path.with.dots"]["next.part"]
  "$set.$merge.$push": [1], // pushes to pathed.$set.$merge
  "[bracket\\]prop].$set": "eugh escapes", // sets pathed["bracket]prop"]
});

As an extension if double quotes are allowed in the brackets then automatic escaping of strings can be managed through JSON.stringify(). Consider:

const newData = updatePath(myData, {
  [`[${JSON.stringify(computedName)}].$set`]: "supports primitive values",
});

[FEATURE-REQUEST] Add $keyExists command

I found myself do a lot of this

const updateDef = {
  [someKey]: {$push: newArray}
}

if (!state[someKey]) {
  updateDef[someKey]: {$set: newArray}
}

update(state, updateDef)

Could we add another command like $keyExists and it work like this:

const updateDef = {
  [someKey]: {$keyExists: [ {$push: newArray}, {$set: newArray} ]}
}

Happy to make a pull request if you guy found this feature would be helpful

import statement in readme seems to be wrong

The docs have this snippet:

// import update from 'react-addons-update';
import update from 'immutability-helper';

But the export looks like this:

module.exports = newContext();

Which works when you follow the docs on react-addons-update (seeing as it's a drop-in replacement) for the import:

// var update = require('react-addons-update');
var update = require('immutability-helper');

But it doesn't work when you use a bundler to transpile from ES6, because the docs' ES6-style default import is misleading (this particular one is from my Webpack project):

Uncaught TypeError: immutability_helper_1.default is not a function

So should the interface be changed or the docs updated? I'm guessing the latter.

Incompatibility with react-addons-update

When trying to replace [email protected] with [email protected] I ran into the following incompatibility. Is this expected behavior?

var update1 = require('react-addons-update');
var update2 = require('immutability-helper');

var x = {a: [1, 2, 3], b: "me"};

var mod = {
  a: {$splice: [[0, 2]]},
  $merge: {b: "you"},
}

console.log(JSON.stringify(update1(x, mod))); // {"a":[3],"b":"you"}
console.log(JSON.stringify(update2(x, mod))); // {"a":[1,2,3],"b":"you"}

How to update an array element given index stored in a variable

While the following code in the doc works fine:

var collection = [1, 2, {a: [12, 17, 15]}];
var newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});

If I use a variable to store the element index, as in the code:

var idx = 2;
var collection = [1, 2, {a: [12, 17, 15]}];
var newCollection = update(collection, {idx: {a: {$splice: [[1, 1, 13, 14]]}}});

the following exception will be raised:

TypeError: Cannot read property 'a' of undefined
    at update (/home/hong/Sencha/web/website/node_modules/immutability-helper/index.js:50:42)
    at update (/home/hong/Sencha/web/website/node_modules/immutability-helper/index.js:50:29)

Quite often in a list the index of the element to be updated is not known beforehand but found out via the findIndex method and saved in a variable.

How shall the code be written in this case?

support $unset

Could you please implement the $unset function? Thanks

Dot notation support

The MongoDB query language supports dot notion. For example:

db.jobs.find({"customer.first_name": someValue});

I see that immutability helper supports the Mongo commands, but dot notation does not seem be supported. Is that correct?

For example, the following code updates a a property customer.first_name on the root of job, rather than finding/updating job.customer.first_name.

update(job, {"customer.first_name": {$set: someValue}})

I understand that I could manually drill down to the the proper place. But, what I am really trying to do is use a variable representing the location of the value to update

For example:

// inputData = {name: "customer.first_name", value: "John"}
// inputData = {name: "address.zip", value: "12345"}
update(job, {`${inputData.name}`: {$set: inputData.value}});

I am I understanding properly that immutability-helper does not support dot notation as stated?

Thanks!!

Autovivification documentation is misleading

Thanks for documenting autovivification in your README. This will provide a response to the many people who run into this, as you've no doubt noticed by the number of github tickets related to this (on the react as well as your bugtracker). A few points though:

  1. The fundamental reason why autovivifying arrays in JS is difficult is that the same [] operator is used for both array and object access so there is no way to disambiguate which one an autovivification is intended to create. However, update is not implementing JS, but instead its own mini-language. There's no reason that we can't decide "path" autovivification is only supported for objects, which in my experience is what is needed in the vast majority of instances (note that all tickets on the react and your bugtrackers are suggesting object autovivification only).

  2. Even in the cases where you wish to autovivify an array, $push, $splice, and $unshift can be used to create arrays with no ambiguity (at the leaf level only). Again, anecdotally, $push seems to be a much more common way of adding to an existing array than $set. Since it's obvious $push and company intend to operate on arrays, there is no problem autovivifying in these cases.

  3. Your suggested example using $apply has three issues from my perspective:

    • $apply updates cannot be transferred between client and server since functions cannot be serialised
    • Each $apply has two code paths (the default []/{} path and the path for when the target already exists) and therefore ought to be tested in both scenarios
    • Although subjective, to me this method seems more complicated and difficult to maintain
  4. Adding autovification to update is not "practically impossible". In fact, I have implemented it in my version: update-immutable. If you choose to not implement autovivification in your module (a decision I sympathise but do not agree with) then can you at least please link to a "dissenting opinion" on this topic?

Regards,

Doug

Using $merge with index to update item

Hi,

I'm trying to $merge data using the index of an item when rendered. However, I could not see an example showing how to do this, and my attempts have failed.

Basically I want to create a new "new" in the data as well.

I created a codeSandbox to show my attempt: https://codesandbox.io/s/ADARgvlxB

Turn data from this:

{
	"foo": [{
			"id": "1",
			"bar": {
				"baz": "ABC"
			}
		},
		{
			"id": "2",
			"bar": {
				"baz": "DEF"
			}
		}
	]
}

To this

{
	"foo": [{
			"id": "1",
                        "new": "test"
			"bar": {
				"baz": "ABC"
			}
		},
		{
			"id": "2",
			"bar": {
				"baz": "DEF"
			}
		}
	]
}
  • potentially it can just add "new":"" to the other entry, as this might be needed to keep the json valid?

getting error on merge

Error:

Uncaught (in promise) Error: update(): $merge expects a target of type 'object'; got undefined
at invariant (invariant.js:44)
at update (update.js:70)
at update (update.js:104)

line throwing error:
return update( state, {item: {$merge: {[action.key]: action.value}}});

any idea why this is happening? I checked typeof for each and they are both objects.

What's the advantage of immutability-helper?

I write some code with immutability-helper, but I have not experience its advantage yet.

Here is some code:

case 1: process the load more of list.

 _loadMore() {
        const {page, query, filter: {title}} = this.state;
        const nextPage = page + 1;
        this._fetchData(query, nextPage).then(data => {
            const {books} = data;

            //create new ref way
            const oldBooks = this.state.books;
            const newBooks = Array.prototype.concat.apply(oldBooks, books);
            let newState =  {
                books: newBooks,
                page: nextPage
            }

            //immutable-helper way
            // let newState = update(this.state, {
            //     books: {$push: books},
            //     page: {$set: nextPage}
            // });
   
            this.setState(newState, this._refreshScroller);
        })
    }

experience: maybe update function is little convenient.

case 2: add a field to some object of list.

_toggleIntro(index) {
        //1. use immutable-helper
        const newState = update(this.state, {
            books: {$apply: books => {
                let target = books[index];
                const newTarget = update(target, {
                    showIntro: {$apply: showIntro => {
                        if(typeof showIntro === 'undefined') {   
                            return true;
                        } else {
                            return !showIntro;
                        }
                    }}
                })
                //still need es7 array/object spread property here?
                return [...books.slice(0, index), newTarget, ...books.slice(index + 1)];
            }}
        })

        // 2. use es7 object spread property to create new copy
        // const {books} = this.state;
        // const target = books[index]; 
        // const showIntro = target.showIntro;
        // const newState = {
        //     ...this.state,
        //     books: [
        //         ...books.slice(0, index),
        //         Object.assign({}, target, {showIntro: typeof showIntro === 'undefined' ? true : !showIntro}),
        //         ...books.slice(index + 1)
        //     ]
        // }
        console.log('this.state', this.state);   //both of the ways do not change the `source` data.
        console.log('newState', newState);
        this.setState(newState);
    }

experience: still, maybe update $apply, $push, $merge are convenient?
You don't have to create some temporary variable to store your new copy?

Thanks for answer.immutability-helper equal with create new copy? Am I right?

------- update: --------

Maybe $push, $set, $splice, $merge, $apply just are the packaged of CURD operator?

Like the methods ImmutableUpdatePatterns talk about?

$unshift command produces results different from react-addons-update

var update1 = require('react-addons-update'); // 15.3.2
var update2 = require('immutability-helper'); // 2.0.0

var original = [1, 2, 3];
var r = update1(original, {$unshift: [4, 5, 6]});
var i = update2(original, {$unshift: [4, 5, 6]});

console.log(r); // [ 6, 5, 4, 1, 2, 3 ]
console.log(i); // [ 4, 5, 6, 1, 2, 3 ]

immutability-helper can't handle arrays the same way as react-addons-update

immutability-helper is advertised as a drop-in replacement for the react-addons-update. However it has different behaviour in regarding to arrays:

import updateOld from 'react-addons-update';
import updateNew from 'immutability-helper';

[updateOld, updateNew].map((update, index) => test(`${index}`, () => {
    // Given
    const value = {field: [{a: 0}]};
    // When
    const updatedValue = update(value, {field: [{a: {$set: 1}}]});
    // Then
    expect(updatedValue.field[0].a).toEqual(1);
}));
 FAIL  test/javascript/Features.test.jsx
  ● 1

    Invariant Violation: update(): You provided an invalid spec to update(). The spec may not contain an array except as the value of $set, $push, $unshift, $splice or any custom command allowing an array value.
      
      at invariant (node_modules/invariant/invariant.js:42:15)
      at update (node_modules/immutability-helper/index.js:42:5)
      at update (node_modules/immutability-helper/index.js:65:31)
      at Object.<anonymous> (test/javascript/Features.test.jsx:26:28)
      at process._tickCallback (internal/process/next_tick.js:103:7)

  ✓ 0
  ✕ 1 (1ms)
  class
    ✓ arrow function as class property should stay bound (1ms)

It would be nice if the immutability-helper would be aligned with the react-addons-update to update internals of arrays.

Documentation on update.extend?

It looks like this is designed to allow user-defined commands. ie update.extend('$removeNull', *some function*).

If that's the case I'll be happy to contribute a PR to add that to the README.

Bug? Unexpected effect of {$set: undefined} to object

Testing on version: [email protected]

Not sure this is a bug or not.

When directly setting undefined to object

const obj = {}
obj.x = undefined
Object.keys(obj) === ['x']

set undefined by immutability-helper

const obj2 = immutabilityHelper({}, { x: { $set: undefined } })
Object.keys(obj2) === []  // WITHOUT 'x'

I was expecting undefined will be set to obj2 and Object.keys(obj2) === ['x'].

update undefined to object which already have x

const obj3 = immutabilityHelper({ x: 1 }, { x: { $set: undefined } })
Object.keys(obj3) === ['x']  // WITH 'x'
obj3.x === undefined

Unable to resolve module 'immutability-helper'

Hi , I am using React Native 0.43 with Android Platfrom.
Even I have import update from 'immutability-helper' it still give me an error that -
Unable to resolve module 'immutability-helper' rom [MY_DIRECTORY];Modules does not exist in the module map or in theres directories ....

$unset directive does not process arrays

$unset directive expects an array, but processes only one element for the array, other elements are ignored.

Here is an example:

let state = {
  foo: true,
  bar: true,
  baz: true
};
let newState = update(state, {$unset: ['foo', 'bar']});
console.log(newState);
// prints {foo: true, baz: true}
// expected {baz: true}

push into array when key is not define

let a = {};
let b = update(a, {c: {$push: [4, 5, 6]}});
console.log("b => ", b); // expected output => b =>  { c: [ 4, 5, 6 ] }

but error : update(): expected target of $push to be an array; got undefined.
What should i do insert new field into a when it doesn't exist

Mutating objects when index not available

Hi,

I am having trouble using the immutability-helper on data as the index it gets is incorrect.

I have created a side-by-side example, one uses state, and the other uses css to hide values (and thus the index remains the same.

How can I update/modify items when the index is not available?

Thanks.

I put this in a codeSandbox to:
https://codesandbox.io/s/o2rDJZ7pz

class App extends React.Component {
  ...
  remove = (e, index) => {
    this.setState({
      movies: update(this.state.movies, { $splice: [[index, 1]] }),
    });
  };
  ....
            {moviesToHide.map((x, index) => {
              return (
                <ResultState
                  key={x.id}
                  result={x}
                  index={index}
                  remove={e => this.remove(e, index)}
                />
              );
            })}
          </div>

A little help pushing array into state object

I have my state

const initialState = {
    photos: [],
    hasData:false,
};

And my reducer 

switch (action.type) {
        case actionTypes.INSERT_PHOTO:
            return update(...state, {$push: [action.data]});
        case actionTypes.CLEAR_PHOTOS:
            return [];
        default:
            return state;
    }

Which works great but it's not pushing the new item into my array overwrites my entire array

return update(...state, {$push: [action.data]});

How do I make it where it pushes the new array in the correct state element

Add support for symbols as keys for $merge

Hi there,

as it seems the $merge command currently does not support symbols for the keys. Probably because of line 96. Adding support for Symbol should be easy, at least if only modern browsers are considered with native Symbol support. For older browsers it will be trickier and polyfills must be used.

If you are interested in this, I would gladly create a pull request and we can see whether it is good enough and how we can improve it.

Error: update(): $merge expects a target of type 'object'; got undefined

I get the following error from the code below:
Error: update(): $merge expects a target of type 'object'; got undefined

I am trying to merge 2 arrays while only updating certain values in the items in the original array. For example, I want to update the status and updated properties but not the members array property.

I think that the issue may be with the use of index in the update method but that is just a guess. Any ideas? If there is a better approach, I would like to know it.

const oldProjects = [
{id: 1, members:[{name: 'Al'},{name: 'Joe'}], status: 'new', updated: '2017-05-19 12:00:00'},
];

const newProjects = [
{id: 1, members:[], status: 'in-progress', updated: '2017-05-19 14:05:00'},
{id: 2, members:[], status: 'new', updated: '2017-05-19 14:10:00'},
{id: 3, members:[], status: 'completed', updated: '2017-05-19 14:15:00'},
];

let newState = oldProjects;

newProjects.forEach(np => {
const index = oldProjects.findIndex(op => op.id === np.id);
if (index === -1) {
newState = update(newState, {$push: np});
} else {
newState = update(newState, {index: {$merge: {
status: np.status,
updated: np.updated,
}}});
}
});

Changing a file objects name in React.js state

Good Day!
Using React and react-dropzone.

Users can drop files in , a list appears with file names in input boxes so they can change filenames if needed.
The filelist is set to setState({files: acceptedFiles })
I have the inputs onchange wired to an onchange function.

I quickly found error of read-only for name on #<File> object and came across advice to use update from immutability helpers.

So I came up with this

let id = event.target.id; 
this.setState(update(this.state.files[id], {name: {$set: event.target.value }}));  

However upon editing the file name in the input that now produces
Uncaught TypeError: Failed to construct 'File': 2 arguments required, but only 0 present.

I get what that means just have no idea how to modify the update() to satisfy the File recreation.

Is this a good place to ask or move over to Stackoverflow?

Thank you if anyone can chime in.

Order-independent $splice?

This is actually a problem I ran into with react-addons-update, but that's deprecated now, so I'm filing it here.

I would expect these two operations to give the same result:

> var update = require('immutability-helper');
> update([0,1,2,3,4,5], {$splice: [[1,1],[3,1]]})
[ 0, 2, 3, 5 ]
> update([0,1,2,3,4,5], {$splice: [[3,1],[1,1]]})
[ 0, 2, 4, 5 ]

i.e., if I want to remove indices 1 and 3 I wouldn't expect them to "shift" in the middle of the operation.

$splice works sequentially

I'm not sure this is formally a bug but it definitely deviates from expectations from my standpoint.

const res = update([1,2,3,4], {$splice: [[0,1],[1,1]]})
// res = [2, 4]

Since the spec for $splice is an array of arrays, I think the targeted indices should not change during the operation. I can't think of many use cases where you could safely use $splice and know ahead of time all the indices of the elements you intend to remove.

Do not update when data is the same

It would be good if update function could return previous data if changed variable is the same

i mean
let a = {b: {c: {d : 5}}};
let z = update(a, {b: {c: {d : {$set: 5}}});
here 'z' changes even though value is the same.
Right now i have a performance issue with react application, cause after update i receive new object most of the times with the same value as previous.

I believe Implementing this feature would speed up a react application

Preserve referential equality if possible

We’re planning to deprecate react-addons-update so if you’d like to continue the development we’ll be happy to point people to your repo instead.

If you’re up for it, I wondered if you’d like to port over the changes made in facebook/react#6353? We planned to merge this but it probably won’t make it into 15 so I think it would be best to just do the same thing in this project now. Feel free to copy the tests and then tweak the implementation to match facebook/react#6353 as you see fit.

Cheers!

Return same instance when values don't change

I'm considering adding some checks in $set, $merge and $apply so that if the resulting object has the same values, return the original instance. This way the resulting and original objects can be compared using ===.

I want to know your opinion about this and whether you would accept a PR with those changes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.