https://github.com/zestia/ember-validation
Simple validation utils for Ember apps
https://github.com/zestia/ember-validation
Last synced: 11 months ago
JSON representation
Simple validation utils for Ember apps
- Host: GitHub
- URL: https://github.com/zestia/ember-validation
- Owner: zestia
- License: mit
- Created: 2018-01-10T09:53:12.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2025-07-07T14:16:44.000Z (11 months ago)
- Last Synced: 2025-07-07T14:59:03.605Z (11 months ago)
- Language: JavaScript
- Homepage:
- Size: 6.3 MB
- Stars: 8
- Watchers: 16
- Forks: 4
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
# @zestia/ember-validation
[npm-badge]: https://img.shields.io/npm/v/@zestia/ember-validation.svg
[npm-badge-url]: https://www.npmjs.com/package/@zestia/ember-validation
[github-actions-badge]: https://github.com/zestia/ember-validation/workflows/CI/badge.svg
[github-actions-url]: https://github.com/zestia/ember-validation/actions
[ember-observer-badge]: https://emberobserver.com/badges/-zestia-ember-validation.svg
[ember-observer-url]: https://emberobserver.com/addons/@zestia/ember-validation
This lightweight addon lets you validate an object, or an array of objects.
It works by running one or more functions against each property on the object (or array of objects), and returns a matching structure containing an array of messages that describe each property.
### Installation
```
ember install @zestia/ember-validation
```
Add the following to `~/.npmrc` to pull @zestia scoped packages from Github instead of NPM.
```
@zestia:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=
```
## Demo
https://zestia.github.io/ember-validation
## Features
- Validates objects ✔︎
- Validates arrays ✔︎
- [Internationalisation](#internationalisation) ✔︎
- [async constraints](#constraints) ✔︎
- [adhoc constraints](#adhoc-constraints) ✔︎
- [dynamic constraints](#dynamic-constraints) ✔︎
- Uses [date-fns](https://date-fns.org) for date validation. ✔︎
- Simple [restructuring](#utils) of error messages ✔︎
## Notes
- Making a constraint is as simple as writing a function that returns nothing if it passes, or a string if it fails.
## Example
```javascript
import validate from '@zestia/ember-validation';
import {
present,
maxLength,
truthy,
email,
date
} from '@zestia/ember-validation/constraints';
const person = {
id: 1,
name: '',
emailAddress: 'joe@bloggs',
dateOfBirth: null,
terms: false
};
const constraints = {
name() {
return [
present({ message: 'Please enter your name' }),
maxLength({ max: 255 })
];
},
emailAddress() {
return [present(), email()];
},
dateOfBirth() {
return [present(), date({ format: 'dd/MM/yyyy' })];
},
terms() {
return [truthy({ message: 'Please accept the terms' })];
}
};
const errors = await validate(person, constraints);
/**
* {
* name: [
* 'Please enter your name'
* ],
* terms: [
* 'Please accept the terms'
* ],
* emailAddress: [
* 'Invalid email'
* ],
* dateOfBirth: [
* 'Required value',
* 'Invalid date, expecting dd/MM/yyyy'
* ]
* }
*/
```
## Adhoc Constraints
You can validate properties that aren't actually on the object being validated. Here is a contrived example...
```javascript
const person = {
firstName: 'Joe',
lastName: 'Bloggs'
};
const constraints = {
firstName() {
return [present()];
},
lastName() {
return [present()];
},
name() {
return [nameIsUnique];
}
};
const errors = await validate(person, constraints);
/**
* {
* firstName: null,
* lastName: null,
* name: ['Must be unique']
* }
*/
const names = ['Joe Bloggs'];
function nameIsUnique(value, object) {
if (names.includes(`${object.firstName} ${object.lastName}`)) {
return;
}
return 'Must be unique';
}
```
## Dynamic Constraints
Because constraints are functions, this allows for a very powerful approach for validating arrays of objects.
For example, imagine you have an array of items of a _varying types_.
```javascript
const items = [
{ id: 1, value: '', type: 'text' },
{ id: 2, value: '', type: 'number' },
{ id: 3, value: '', type: 'email' },
{ id: 4, value: '', type: 'date' }
];
const constraints = (item) => {
return {
value() {
switch (item.type) {
case 'text':
return [present()];
case 'number':
return [present(), number()];
case: 'email':
return [present(), email()];
case: 'date':
return [present(), date({ format: 'dd/MM/yyyy' })];
default:
return [];
}
}
};
}
const errors = await validate(items, constraints);
/*
* [
* {
* value: ['Required value']
* },
* {
* value: ['Required value', 'Invalid number']
* },
* {
* value: ['Required value', 'Invalid email']
* },
* {
* value: ['Required value', 'Invalid date, expecting dd/MM/yyyy']
* }
* ]
*/
```
## Constraints
The following constraints come with this addon. Creating a constraint is as simple as making a function that returns a string if the constraint has failed. Constraints can be asynchronous too.
- `bigDecimal`
- `date`
- `email`
- `greaterThan`
- `lessThan`
- `maxLength`
- `minLength`
- `number`
- `phoneNumber`
- `present`
- `truthy`
## Internationalisation
There are a few approaches you can take to internationalise the error messages. The most obvious one would be to set the message property as the translated string, e.g.
```javascript
message: this.intl.t('too-large');
```
Alternatively, you could set the message just as the key, and internationalise it later in handlebars, e.g.
```javascript
message: 'too-large';
```
Or, as of version 5, you can provide a key, e.g.
```javascript
key: 'too-large';
```
...along with a function that will be called for each failed constraint, e.g.
```javascript
import { setMessageFn } from '@zestia/ember-validation';
export function initialize(appInstance) {
const intl = this.owner.lookup('service:intl');
setMessageFn((key, tokens) => intl.t(`validation.${key}`, tokens));
}
```
## Utils
- `setMessageFn`
Sets the function that will build a string for a given constraint
- `messageFor`
Should be used as the return value of constraint function
- `flattenErrors`
Flattens a validation result into a single array of _all_ the messages
- `collateErrors`
Flattens a validation result into an array of the messages for each field