Skema: Async Validation

Examples to show how to validate a variable asynchronously.

by kaelzhang

HTML

<script src="https://unpkg.com/skema/umd/jsfiddle.js"></script>
<script src="https://unpkg.com/skema/umd/skema.min.js"></script>

JavaScript

// By default, skema works synchronously.
// To make the validators works asynchronously,
// we could use the options of method `.from()`

const {type} = Skema

// Print success message with label
const s = label => {
	return msg => success(label, msg)
}

const e = label => {
	return error => fail(label, error.message, error) 
}

// 1
const PositiveNumber = type({
  validate (v) {
    if (typeof v !== 'number') {
      return false
    }

    if (v > 0) {
      return true
    }

    throw 'must be positive'
  }
})

// Makes .from() works asynchronously
const options = {async: true}

PositiveNumber.from(1, options).then(s('1-1'))
PositiveNumber.from('1', options).catch(e('1-2'))
PositiveNumber.from(-1, options).catch(e('1-3'))

// If runs sync
success('1-4', PositiveNumber.from(1))

// 2. Real async valdidator
const BigNumber = type({
  validate (v) {
    return new Promise((resolve, reject) => {
      if (typeof v !== 'number') {
        return reject('not a number')
      }

      if (v <= 0) {
        return reject('must be positive')
      }

      if (v < 10000) {
        // resolve `false` also indicates a failure
        return resolve(false)
      }

      resolve(true)
    })
  }
})

BigNumber.from(-1, options).catch(e('2-1'))
BigNumber.from('-1', options).catch(e('2-2'))
BigNumber.from(10000, options).then(s('2-3'))

// 3. Duplex: return value with Promise.reject/resolve
const BigNumber2 = type({
  validate (v) {
    if (typeof v !== 'number') {
      return Promise.reject('not a number')
    }

    if (v <= 0) {
      return Promise.reject('must be positive')
    }

    if (v < 10000) {
      // resolve `false` also indicates a failure
      return Promise.resolve(false)
    }

    return true
  }
})
// The same effect as `BigNumber`
BigNumber2.from(-1, options).catch(e('3-1'))