Code Monkey home page Code Monkey logo

ember-changeset-conditional-validations's Introduction

Build Status Ember Observer Score

ember-changeset-conditional-validations

An extra validator for conditional validations with ember-changeset-validations.

Installation

ember install ember-changeset-conditional-validations

Basic Usage

Let's say you want to validate a user's settings. Only if the payment method is a credit card should the credit card number validations be applied.

import { validatePresence, validateLength } from 'ember-changeset-validations/validators';
import validateSometimes from 'ember-changeset-conditional-validations/validators/sometimes';

export default {
  creditCardNumber: validateSometimes([
    validatePresence(true),
    validateLength({ is: 16 })
  ], function(changes, content) {
    return this.get('paymentMethod.isCreditCard');
  })
};

validateSometimes() takes 2 arguments. The first is a validator or an array of validators you want applied to the attribute. The second argument is a callback function which represents the condition. If the condition callback returns true, the rules will be added. This callback function will be invoked with the changeset's changes and content. The callback will also be invoked with its this value set to an object that has a get() method for accessing a property. this.get(property) first proxies to the changes and then the underlying content, and has the same semantics as Ember.get().

import Changeset from 'ember-changeset';
import lookupValidator from 'ember-changeset-validations';
import Validations from './../validations/settings';

let settings = {};
let changeset = new Changeset(settings, lookupValidator(Validations), Validations);

console.log(changeset.get('isValid')); // true
changeset.set('paymentMethod', {
  isCreditCard: true
});
changeset.validate();
console.log(changeset.get('isValid')); // false
console.log(changeset.get('errors')); // [{key: 'creditCardNumber', validation: ['Credit card number can't be blank', 'Credit card number must be a number']}]
changeset.set('creditCardNumber', '1234567890123456');
changeset.validate();
console.log(changeset.get('isValid')); // true
changeset.set('creditCardNumber', '1234');
changeset.validate();
console.log(changeset.get('isValid')); // false
console.log(changeset.get('errors')); // [{key: 'creditCardNumber', value: '1234', validation: ['Credit card number must be equal to 16']}]
changeset.set('paymentMethod', {
  isCreditCard: false
});
changeset.validate();
console.log(changeset.get('isValid')); // true

Combining Validations with Conditional Validations

You can also have a combination of validations that will always run and conditional validations. For example, say you wanted to validate that a property is a number, but conditionally validate that the number is greater than 5. You could do something like the following:

import { validateNumber } from 'ember-changeset-validations/validators';
import validateSometimes from 'ember-changeset-conditional-validations/validators/sometimes';

export default {
  someProperty: [
    validateNumber({ integer: true }),
    validateSometimes(validateNumber({ gt: 5 }), function() {
      // condition
    })
  ]
};

Let's say in the previous example that you also wanted to conditionally validate that the number is less than 10. You could do something like the following:

import { validateNumber } from 'ember-changeset-validations/validators';
import validateSometimes from 'ember-changeset-conditional-validations/validators/sometimes';

export default {
  someProperty: [
    validateNumber({ integer: true }),
    ...validateSometimes([
      validateNumber({ gt: 5 }),
      validateNumber({ lt: 10 })
    ], function() {
      // condition
    })
  ]
};

Installation

  • git clone <repository-url> this repository
  • cd ember-changeset-conditional-validations
  • npm install

Running

Running Tests

  • npm test (Runs ember try:each to test your addon against multiple Ember versions)
  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit https://ember-cli.com/.

ember-changeset-conditional-validations's People

Contributors

andrewpye avatar ember-tomster avatar henridv avatar sovietspaceship 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

Watchers

 avatar  avatar  avatar

ember-changeset-conditional-validations's Issues

Conditional validations don't update when values used in condition change

This behaviour isn't necessarily a bug โ€“ I understand why it happens, and what the workaround for it is, but I wanted to flag it for visibility and in case anybody has the time and willingness to work on a solution.

Suppose we have a class like

class MyClass {
  count = 0;
  shouldValidateCount = true;
}

and validations for that class like

{
  count: validateSometimes([
    validateNumber({ gt: 0 })
  ], function() {
    return this.get('shouldValidateCount');
  })
}

Then if we create a changeset around an instance of MyClass (with count set to 0 and shouldValidateCount set to true) using those validations, the following happens:

(async function showValidationGotcha() {
  await changeset.validate();
  console.log(changeset.get('isValid')); // false

  changeset.set('shouldValidateCount', false);
  console.log(changeset.get('isValid')); // false, when really should be true
})();

We can of course work around this by explicitly calling changeset.validate() or changeset.validate('count') whenever shouldValidateCount gets set to a new value, but this is clunky and easily forgotten โ€“ and gets hard to manage when an object has a large number of conditional validations.

I'm not familiar with the internals of tracked properties etc., but it'd be awesome if it was possible to tap into a mechanism like that to ensure that the validations for properties with conditions associated with them get recomputed whenever a dependency of that condition is updated ๐Ÿค”

Using static and conditional validators

Is there a method by which conditional validations AND static (always present) validations could be applied to a property? E.g. I want to ALWAYS validate that a property is a number, but conditionally validate that the number is greater than 5.

I was thinking this format should work:

{
  myProp: [
    validateNumber({integer: true}),
    validateSometimes([validateNumber({gt: 5})], function() { /* ... */ })
  ]
}

But this throws errors:

TypeError: validator is not a function
    at handle-multiple-validations.js:53

Merge with ember-changeset-validations

Awesome functionality! โ›ต๏ธ

Would you be willing to consider a merge with ember-changeset-validations?

This functionality is already spread across both ember-changeset and ember-changeset-validations.

Three separate libraries to cover essentially one thing seems a bit excessive. I think all three are awesome, but that they would benefit from being in one package. It would also aid discovery, right now someone may discover only ember-changeset but won't be aware of this library.

Here is one example of another library being merged into ember-changeset-validations:
poteto/ember-changeset-validations#131

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.