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

add u.omitted constant #78

Merged
merged 1 commit into from
Nov 28, 2018
Merged

add u.omitted constant #78

merged 1 commit into from
Nov 28, 2018

Conversation

yanick
Copy link
Contributor

@yanick yanick commented Nov 20, 2018

Right now if one wants to remove properties and update others, we need to do it in two steps: one call to u.omit and one to u.update. This PR adds a u.omitted constant signalling that the property should be omitted (we can't use null or undefined as those could be legit property values we might want to keep).

Copy link
Member

@aaronjensen aaronjensen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I've left some feedback.

README.md Outdated
```js
var user = { email: 'john@aol.com', username: 'john123', authToken: '1211..' };

var result = u({ authToken: _.omitted, active: true }, user);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u.omitted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

urgh. u.cantbelievehowoftenImakethatypo

@@ -414,6 +426,7 @@ function isSensitive(value, key) { return key == 'SSN' }
var result = u({ user: u.omitBy(isSensitive) }, user);

expect(result).to.eql({ user: { email: 'john@aol.com', username: 'john123', authToken: '1211..' } });

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this change please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, eslint got overzealous. All spurious style changes should have been rolled back now.

lib/update.js Outdated
import wrap from './wrap'
import constant from './constant'

const innerOmitted = constant('omitted')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can just be {} since that will work for reference equality. Making it a function that returns the string omitted doesn't seem necessary unless I'm missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you're right, any reference would do. I was just trying to put a reference that could be potentially more telling than an empty object, but that will work just as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps something like { __omitted: true }. Still a reference, just more meaningful if seen in debug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, there are some dangers to relying on reference. If a person has two versions of updeep in their tree, it's possible that this won't work properly. Maybe it should be modeled after however lodash does their placeholder? I don't remember how off the top of my head.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[lodash] Hmmm... I'll have a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I think the ref won't work only if somebody does:

import u1 from 'updeep';
import u2 from './path/to/other/updeep';

u1({ foo: u2.omitted })(x);

which would be rather twisted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree that it's unlikely, if someone has a library that depends on updeep to build custom operators you could get into this situation. That library may export an operator that uses omitted from its version of updeep and if you use it with yours...

Not likely, I agree, but if lodash has an easy way to deal w/ it, it's probably good to follow that pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And unless I'm mistaken, lodash does it by attaching a placeholder attribute to the main exported _ variable: https://github.com/lodash/lodash/blob/4ea8c2ec249be046a0f4ae32539d652194caf74f/.internal/getHolder.js

We should be able to do the same. Give me 5 minutes. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Darn. update is wrapped via wrap before it's exported, so binding would be a little more involved than I thought. And I'm not sure it'd bring any more safety than using the omitted and update from the same u source.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, let's just try a reference for now.

lib/update.js Outdated
@@ -19,7 +25,9 @@ function resolveUpdates(updates, object) {
let updatedValue = value

if (
!Array.isArray(value) && value !== null && typeof value === 'object'
!Array.isArray(value) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm down with prettiering the repo, but I'd prefer it be a separate commit/PR. Could you please amend any of the non-essential changes out?

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

expect(result).to.eql({ b: 3 });
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include a test for a nested object and for an array (what should it do if you omit in an array?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests added.

The _.omitted should skip the property value, no matter if it's a scalar or an array or object, so we should be good there.

The undefined case is if one does:

u({ 3: u.omitted })([ 1,2,3,4,5 ]);

I could add logic to take care of that case, basically do

  if (Array.isArray(defaultedObject)) {
    return updateArray(resolvedUpdates, defaultedObject).filter( item => item !== innerOmitted )
  }

but it just doesn't feel like something anybody would do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess the question is, what should the lib do... throw? Create a sparse array? filter it out as you demonstrate there?

Maybe throwing for now in updateArray would work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with filtering, as one can already do the sparse-y array via u({ 3 => null }), and between throwing an exception and doing something maybe possibly useful in some cases, the latter sounds a smidge better. :-)

@aaronjensen
Copy link
Member

looks like there are some formatting errors, could you run prettier/fix those up, please?

@yanick
Copy link
Contributor Author

yanick commented Nov 27, 2018

done!

@aaronjensen
Copy link
Member

Could you rebase on master when you get a chance please? I think that'll fix the build.

@yanick
Copy link
Contributor Author

yanick commented Nov 27, 2018

done!

@aaronjensen aaronjensen merged commit d8da597 into substantial:master Nov 28, 2018
@aaronjensen
Copy link
Member

Looks great, thank you for your contribution!

@aaronjensen
Copy link
Member

Released as 1.1.0, thanks again.

@yanick
Copy link
Contributor Author

yanick commented Nov 28, 2018

Pleasure was all mine! Thanks! :-)

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

Successfully merging this pull request may close these issues.

2 participants