Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Calling .map() on an instance of Record modifies the original Record #645

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

Closed
bvaughn opened this issue Oct 2, 2015 · 10 comments
Closed

Comments

@bvaughn
Copy link

bvaughn commented Oct 2, 2015

Perhaps I'm missing something, but it seems like there is a problem with the map() function on records:

R = Immutable.Record({
  foo: undefined,
  bar: undefined
})
r0 = new R({
  foo: 'poo',
  bar: 'BAR'
})
r1 = new R({
  foo: 'FOO'
})
console.log(r1.toJS()) // Object {foo: "FOO", bar: undefined}
r2 = r1.map(function(value, key) {
  return value || r0.get(key)
})
console.log(r2) // undefined
console.log(r1.toJS()) // Object {foo: "FOO", bar: "BAR"}
@tomwidmer
Copy link

Definitely looks like a bug (although the documentation is very unclear on what API Record instances actually have access to!).

Should reify be like this:

function reify(iter, seq) {
    return isSeq(iter) ? seq : new iter.constructor(seq);
}

?? That's just adding the 'new' keyword. It fixes your issue for me locally, but I don't know if it's the correct fix. An alternative might be

function reify(iter, seq) {
    return isSeq(iter) ? seq : iter.constructor.call(null, seq);
}

Not sure which fix is the better one!

@bvaughn
Copy link
Author

bvaughn commented Oct 9, 2015

although the documentation is very unclear on what API Record instances actually have access to!

Agreed. The docs are a little unclear on many of the instance methods IMO. I often end up just running them in the console and seeing what happens.

@danielstreit
Copy link
Contributor

I believe this is by design. Record#map operates on this record's values, as opposed to returning a new record.

var r = new R();
r.toJS() // { foo: undefined, bar: undefined }
r.map(() => 10);
r.toJS() // { foo: 10, bar: 10 }

@bvaughn
Copy link
Author

bvaughn commented Oct 24, 2015

Having trouble understanding why any method that mutated an Immutable instance would be intentional.

@AlexGalays
Copy link

That's a terrible behavior if it's intentional. A library called immutableJS should be 100% immutable, it's the sole reason it's useful.

lodash has the same trap: it started as a decent functional lib then added all sort of crap like _.pull, _.pullAt and _.remove to directly mutate arrays.

I don't see how this could be intentional.

@tomwidmer
Copy link

It's undefined behaviour (since Record.map is not documented anywhere). But if the feature does become official, clearly this would be a straightforward bug, hopefully with a straightforward fix (if my fix above is the correct one, it's just a 4 character insertion). As everyone says, there is no way that <immutable object>.map() should modify <immutable object> (unless asMutable or withMutable is used, but map() isn't officially supported on mutable objects in any case).

@rawls238
Copy link
Contributor

rawls238 commented Nov 9, 2015

See this issue: #505

Record.map should not be used.

@bvaughn
Copy link
Author

bvaughn commented Nov 9, 2015

Such methods should not be exposed or publicly accessible then.

@ChrisMarinos
Copy link

Wow, this is an incredibly unexpected behavior. Our project heavily relies on Immutable.js and makes extensive use of Records. This behavior lead to several hours of debugging effort since I didn't think it was possible to mutate the properties of a Record instance once constructed. I offer this feedback not to complain, but to illustrate how seriously this behavior deviates from what I expect as a user of the library.

Hopefully this behavior is not intentional. #505 makes it sound like .map will eventually go away on Records, so hopefully that fixes this and any other ways to modify an instance of a record.

@leebyron
Copy link
Collaborator

leebyron commented Mar 4, 2017

Merging into #505

@leebyron leebyron closed this as completed Mar 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants