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

feat(data-point/reducer-default: Add the ReducerDefault type #194

Merged
merged 9 commits into from
Jan 31, 2018

Conversation

raingerber
Copy link
Contributor

What: Adds the ReducerDefault type (closes #169)

Why: This will add default values to any reducer.

How: Instead of actually creating a new reducer type, this just adds a default property to any existing reducer. The property uses a symbol to avoid any future conflicts.

Checklist:

  • Has Breaking changes
  • Documentation
  • Tests
  • Ready to be merged

@raingerber raingerber self-assigned this Jan 30, 2018
### <a name="reducer-default">withDefault</a>

The **withDefault** reducer adds a default value to any reducer type. If the reducer resolves to `null`, `undefined`, `NaN`, or `''`,
the default is returned instead.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default value overwrites null, undefined, NaN, '' (but it does not overwrite 0 or false). If anybody has opinions about this I'm open to changing it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

perfect!

reducer[REDUCER_SYMBOL] = true
reducer[IS_REDUCER] = true
if (_.has(options, 'default')) {
reducer[DEFAULT_VALUE] = { value: options.default }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

because the default is wrapped in this object, the hasDefault function still returns true if the default value is falsy

@coveralls
Copy link

coveralls commented Jan 30, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling af04120 on raingerber:reducer-defaults into 6aab266 on ViacomInc:master.

if (hasDefault(reducer)) {
const _default = reducer[DEFAULT_VALUE].value
const afterResolve = reducers.ReducerDefault.resolve
return resolve.then(acc => afterResolve(acc, _default))
Copy link
Contributor Author

@raingerber raingerber Jan 30, 2018

Choose a reason for hiding this comment

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

I thought about using the default when a reducer throws an error:

// this instead of the current line 64
return resolve
  .catch(e => ({ value: null }))
  .then(acc => afterResolve(acc, _default))

Any thoughts on doing this? It could even be a setting that's passed to withDefault:

const throwError = () => { throw new Error() }

const reducer = withDefault(throwError, 'DEFAULT_VALUE', { catch: true })

// or just...   withDefault(throwError, 'DEFAULT_VALUE', true)

dataPoint.resolve(reducer, {}) // => 'DEFAULT_VALUE'

@acatl acatl added this to the v2 - new features milestone Jan 31, 2018
Copy link
Collaborator

@acatl acatl left a comment

Choose a reason for hiding this comment

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

clarify or change overwrite of variable + use of isNil

const reducerType = reducers[reducer.type]
if (!reducerType) {
throw new Error(`Reducer type '${reducer.type}' was not recognized`)
let resolve = getResolveFunction(reducer)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are you overwriting resolve here? above line is also setting it, any special reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

overwriting it just because it's one less variable name to think up

*/
function resolve (accumulator, _default) {
let value = accumulator.value
if (Number.isNaN(value) || isNil(value) || value === '') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

looking at isNil in lodash I dont think its worth depending on it, + its documentation might not be what it actually is

https://github.com/lodash/lodash/blob/912d6b04a1f6b732508a6da72a95ec4f96bda154/lodash.js#L11967-L11989

link above is TOO SLOW!!!

 /**
     * Checks if `value` is `null` or `undefined`.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
     * @example
     *
     * _.isNil(null);
     * // => true
     *
     * _.isNil(void 0);
     * // => true
     *
     * _.isNil(NaN);
     * // => false
     */
    function isNil(value) {
      return value == null;
    }

I would recommend instead do a manual check against undefined and null

Copy link
Contributor Author

@raingerber raingerber Jan 31, 2018

Choose a reason for hiding this comment

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

done (I also looked up the lodash source before using isNil though 😊)

acatl
acatl previously approved these changes Jan 31, 2018
Copy link
Collaborator

@acatl acatl left a comment

Choose a reason for hiding this comment

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

;)

@acatl acatl merged commit 69a79bd into ViacomInc:master Jan 31, 2018
@raingerber raingerber deleted the reducer-defaults branch January 31, 2018 17:52
victorsingh pushed a commit to victorsingh/data-point that referenced this pull request Feb 13, 2018
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.

withDefault reducer helper
3 participants