Skip to content
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

support $unset #18

Closed
zhaoyao91 opened this issue Feb 7, 2017 · 15 comments
Closed

support $unset #18

zhaoyao91 opened this issue Feb 7, 2017 · 15 comments

Comments

@zhaoyao91
Copy link

Could you please implement the $unset function? Thanks

@Zertz
Copy link

Zertz commented Feb 11, 2017

You can use { $set: undefined }

@zhaoyao91
Copy link
Author

will {$set: undefined} keep the key in the state object? If so, I am afraid it's not proper for some cases such as key is random ids which are added and removed frequently. If we do not clear the key, the keys will explode.

@kolodny
Copy link
Owner

kolodny commented Feb 12, 2017

There are two things you can do to get this usage. The first is to $apply the object you want to remove the property from:

var state = {
  sub: {
    keep: true,
    remove: true
  }
}

var next = update(state, {
  sub: {
    $apply: function(obj) {
      var copy = Object.assign({}, obj)
      delete copy.remove
      return copy
    }
  }
})
console.log('remove' in next.sub) // false
console.log('keep' in next.sub) // true

The other is to extend the update function to include $unset:

update.extend('$unset', function(keysToRemove, original) {
  var copy = Object.assign({}, original)
  for (const key of keysToRemove) delete copy[key]
  return copy
});

// usage is as follows

var state = {
  sub: {
    keep: true,
    remove: true
  }
}

var next = update(state, {
    sub: {
      $unset: ['remove']
    }
})
console.log('remove' in next.sub) // false
console.log('keep' in next.sub) // true

@kolodny kolodny closed this as completed Feb 12, 2017
@kachkaev
Copy link

Why not include $unset into the library? Seems like a reasonable thing to have.

@mikegleasonjr
Copy link

I agree with @kachkaev this should be included in the standard library, now I have to have a global initialization routine instead of only requiring the library wherever I use it.

@kolodny
Copy link
Owner

kolodny commented Mar 14, 2017

This has been discussion on this in the react repo, I'd rather not include it especially considering you can extend it in as done above. See the comment by @spicyj here

@kachkaev
Copy link

kachkaev commented Mar 14, 2017

@kolodny that comment by @spicyj is 1.5 years old though. I am personally relying on immutability-helper in those projects where I deliberately don't want Immutable.js, so a suggestion to use that library does not look like an option.

Patching update within a project will not be a clean solution, which means that there should be a wrapper npm package that extends update for those who still want $unset. Given that the size of this new feature is only 150 bytes and that it's completely BC, why not to include it into immutability-helper straight away? What are the drawbacks?

@Nandan108
Copy link

Adding $unset would not make this a "crazy DSL" as per the cited comment. I would argue that without it, immutability-helper is actually incomplete. Modifications come in three basic forms: additions, updates, and removals. So why limit this library to the first two, when adding the third only costs 5 lines of code?

@hoytech
Copy link

hoytech commented Apr 19, 2017

$apply doesn't work for many use-cases since functions can't be serialised for transfer between server and client.

My update-immutable package supports $unset:

https://www.npmjs.com/package/update-immutable

My module also implements autovivification which IMO is another feature for update without which it is incomplete. Give it a try, you'll probably see that you no longer have to maintain a lot of initial state skeletons in components. :)

@kolodny
Copy link
Owner

kolodny commented Apr 19, 2017

I seemed to have underestimated the desire for this feature. It will be included in the next release. Thanks to everyone for all the feedback.

@kolodny kolodny reopened this Apr 19, 2017
@kachkaev
Copy link

kachkaev commented Apr 29, 2017

Hi @kolodny,

When about do you think you might release that version? Just wanted to use $unset in a new project and decided to see how the things are 😃

@kolodny
Copy link
Owner

kolodny commented Apr 30, 2017

This is done and released in 2.2.0

@kolodny kolodny closed this as completed Apr 30, 2017
@gbennum
Copy link

gbennum commented Apr 4, 2018

Hi @kolodny,

Are you sure that the $unset function is immutable? I have a redux case using unset that isn't triggering a re-render in components:

    case DELETE_DATA:
      const deleteData = update(state.data, {$unset: [action.id]});
    	return Object.assign({}, state, {
        data: deleteData
      });

When I replaced it with the following, using Lodash's omit function, it did trigger a re-render.

    case DELETE_DATA:
      const deleteData = omit(state.data, action.id);
    	return Object.assign({}, state, {
        data: deleteData
      });

Please let me know if I'm wrong, just wanted to bring this to your attention. I do have the correct version, from my package lock:

"immutability-helper": {
      "version": "2.2.2",
      "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-2.2.2.tgz",
      "integrity": "integrity-key"
    },

@FullstackJack
Copy link

@gbennum Worked for me. 2.6.6

@gbennum
Copy link

gbennum commented Apr 11, 2018

Great! Glad to see I was wrong. I wonder what the difference is between the omit and update that would change the behavior of rendering in components.

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

9 participants