[Mongoose] Async Validators Section

So, mosh teaches a deprecated way of async validation cause i’m getting an error saying isAsync is deprecated and that we should make it a promise which is really confusing to me. Since, i don’t want to learn deprecated information before continuing the course. I’m asking anyone here to show me how to refactor this part below into the new syntax. I looked at the documentation and tried to refactor it myself with no luck.

Deprecated Code

tags: {
    type: Array,
    validate: {
      isAsync: true,
      validator: function (v, callback) {
        setTimeout(() => {
          const result = v && v.length > 0;
          callback(result);
        }, 4000);
      },
      message: "A course should have at least one tag",
    },
  },

Valid Code Documentation:

1 Like

Try this StackOverflow answer: Mongoose: the isAsync option for custom validators is deprecated.

1 Like

I solved it this way

tags: {
type: Array,
validate: {
validator: async function (v) {
return await checkTags(v);
},
message: "course shoud have at least one tag"
}
},

And the function

async function checkTags(v) {
  return new Promise((resolve, reject) => {
    setTimeout(()=>{  
        resolve(v && v.length > 0);        

    }, 2000);
  }); 
}
4 Likes

The easiest way to solve this issue is to use Promise instead of Async.
This is how I have solved this and it’s working fine

You can also check out this link for further details https://javascript.plainenglish.io/store-clean-data-by-validating-models-with-mongoose-f6453dbdbff9

Happy coding :slight_smile:

9 Likes

You are a life-saver, cheers mate. Thankyou

1 Like

There are two ways for an promise-based async validator to fail:

  1. If the promise rejects, Mongoose assumes the validator failed with the given error.
validator: function(v) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const result = v && v.length > 0;
			if (!result) {
				reject(new Error());
			}
		}, 4000);
	});
},

Return from the console:
Course validation failed: tags: Validator failed for path tags with value null

  1. If the promise resolves to false, Mongoose assumes the validator failed and creates an error with the given message.
validator: function(v) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const result = v && v.length > 0;
			resolve(result);
		}, 4000);
	});
},

Return from the console:
Course validation failed: tags: A course should have at least one tag.Preformatted text

2 Likes

nice one, but don’t need to add async before checkTags

The above solutions were close but didn’t quite work for me. In this solution the validator creates a Promise, and uses an if…else to either resolve() or reject().

    tags: {
      type: Array,
      validate: {
        validator: function (v) {
          return new Promise((resolve, reject) => {
            setTimeout(() => {
              // Do some async work
              const result = v && v.length > 0;
              if (result) {
                resolve();
              } else {
                reject(new Error('A course should have at least one tag.'));
              }
            }, 4000);
          });
        },
      },
    },