Skip to content

Instantly share code, notes, and snippets.

@tdwesten
Last active April 27, 2023 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tdwesten/cbcb9c44b36157dc8f20766fe10a6b4e to your computer and use it in GitHub Desktop.
Save tdwesten/cbcb9c44b36157dc8f20766fe10a6b4e to your computer and use it in GitHub Desktop.
Ember-Changeset async validate sometimes (promise)
import { get } from '@ember/object'
export default class AsyncValidateSometimes {
constructor(validators, condition) {
this.validators = validators
this.condition = condition
}
async validate(key, newValue, oldValue, changes, content) {
if (Array.isArray(this.validators)) {
return this.validators.map((validator) => {
return this.guardValidatorWithCondition(validator).bind(this)
})
} else {
const customValidateFn = await this.guardValidatorWithCondition(
this.validators
).bind(this)
return customValidateFn(key, newValue, oldValue, changes, content)
}
}
guardValidatorWithCondition(validator) {
return function (key, newValue, oldValue, changes, content) {
let thisValue = {
get(property) {
if (property.includes('.')) {
let changesValue = get(changes, property)
if (typeof changesValue !== 'undefined') {
return changesValue
}
// Check if the `changes` value is explicitly undefined,
// or if it's not present at all.
let pathSegments = property.split('.')
let propName = pathSegments.pop()
let objPath = pathSegments.join('.')
let obj = get(changes, objPath)
if (obj && obj.hasOwnProperty && obj.hasOwnProperty(propName)) {
return changesValue
}
return get(content, property)
}
if (changes.hasOwnProperty(property)) {
return get(changes, property)
} else {
return get(content, property)
}
},
}
const AsyncFunction = Object.getPrototypeOf(
async function () {}
).constructor
const isAsync = this.condition instanceof AsyncFunction
if (isAsync) {
return this.condition
.call(thisValue, changes, content)
.then((result) => {
if (result && key) {
return validator(key, newValue, oldValue, changes, content)
}
return true
})
} else {
if (this.condition.call(thisValue, changes, content)) {
return validator(key, newValue, oldValue, changes, content)
}
return true
}
}
}
}
import {
validatePresence,
} from 'ember-changeset-validations/validators'
import AsyncValidateSometimes from '../validators/async-validate-sometimes'
const CheckoutValidations = {
reference: validatePresence({
presence: true,
message: 'Reference is required',
}),
shippingFirstName: new AsyncValidateSometimes(
validatePresence({
presence: true,
message: 'First name is required',
}),
validateIfCustomAddress
),
shippingLastName: new AsyncValidateSometimes(
validatePresence({
presence: true,
message: 'Last name is required',
}),
validateIfCustomAddress
),
shippingPhone: new AsyncValidateSometimes(
[
validateFormat({ type: 'phone' }),
],
validateIfCustomAddress
),
}
async function validateIfCustomAddress(changes, content) {
return await content.isCustomAddress // isCustomAddress is a Promise
}
export default CheckoutValidations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment