16

I am working on redux-form atm and found the piece of code. Its working for me but is there any cleaner way to write this in ES6 style?

const asyncValidate = (values/* , dispatch */) => {
  return new Promise((resolve, reject) => {
    try {
      if (['john', 'paul', 'george', 'ringo'].includes(values.name)) {
        const error = {
          name: 'That username is taken'
        };
        throw error;
      }
      resolve();
    } catch (e) {
      reject(e);
    }
  });
};

I would appreciate your help


Solution

const asyncValidate = (values/* , dispatch */) => {
  return new Promise((resolve, reject) => {
    const errors = {};
    if (['john', 'paul', 'george', 'ringo'].includes(values.name)) {
      errors.name = 'That username is taken';
    }
    reject(errors);
  });
};

probably cleaner way?!

2 Answers 2

45

try/catch is redundant in promise chains and promise executor functions.

Any error thrown is automatically converted to a rejection of the promise you're supposed to return. The promise code calling your function takes care of this. So just do:

const asyncValidate = values => new Promise(resolve => {
  if (['john', 'paul', 'george', 'ringo'].includes(values.name)) {
    throw { name: 'That username is taken'};
  }
  resolve();
});

and it gets converted to a rejection.

Sign up to request clarification or add additional context in comments.

1 Comment

good explanation! Any unhandled exception inside a promise constructor is automatically wrapped inside a rejected promise. This is also true for the newly created promises inside a then() which makes it easy to just use throw() inside. (see 25.4.1.3.2 in ES6 spec)
1

You can use Conditional (ternary) Operator to simplify if-statement, also you don't need a catch block here:

//ES5
const asyncValidate = (values) => {
    return new Promise((resolve, reject) => {
        ['john', 'paul', 'george', 'ringo'].includes(values.name) ? reject({ name: 'That username is taken' }) : resolve();
    });
};

//ES6 - using "generators"
const asyncValidate = function* (values) {
    return yield ['john', 'paul', 'george', 'ringo'].includes(values.name) ? Promise.reject('That username is taken') : Promise.resolve();
}

2 Comments

This doesnt work for me: "Uncaught Error: asyncValidate function passed to reduxForm must return a promise"
Returning a generator of promises is not the same as returning a promise?! Maybe what you meant was an ES8 async function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.