Проверка схемы Mongoose против внешнего API - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть схема мангуста, подобная следующей:

const User: Schema = new Schema({
// some other fields
email: {type: String, unique: true, require: true, validate: [myValidator, 'invalid email provided'],
// some more fields
)};

MyValidator использует функцию validatorJS isEmail, чтобы проверить, был ли введен действительный адрес электронной почты, и выглядит ли он следующим образом:

function myValidator(email: String) {
   return isEmail(email: String, {require_tld: true, domain_specific_validation: true});

Пока все это работает, как и ожидалось. Но теперь у меня есть следующая проблема, которая может быть связана с моим ограниченным пониманием Typescript / JaveScript. Я хотел бы расширить myValidator, чтобы проверить введенный адрес электронной почты по внешнему API.

Пока я пробовал что-то вроде этого:

function myValidator(email: String) {
     let isValid = false;
     request('https://disposable.debounce.io/?email=' + email, { json:     true }, async (err, res, body) => {
     if (err) { return console.log(err); }
     isValid = body.disposable;
     });
     if (isValid && !isEmail(email, {require_tld: true, domain_specific_validation: true})) {
     return false;
}

Но это, очевидно, не сработает, так как запрос является асинхронной операцией, поэтому isValid всегда будет false

Поэтому я «попытался» сделать эту функцию асинхронной / ожидающей.

function myValidator(email: String) {
  const remoteCheck = function() {
    return new Promise(function() {
      request('https://disposable.debounce.io/?email=' + email, { json: true }, async (err, res, body) => {
          if (err) { return console.log(err); }
          return body.disposable;
        });
    });
  };
  async function f() {
    const isValid = await remoteCheck();
    if (isValid === true) {
      return false;
    } else {
      isEmail(email, {require_tld: true, domain_specific_validation: true});
      }
    }
    if(f()) {
    return true; 
    } else {
    return false;
  }

Но это дает мне ошибку, потому что эту функцию нельзя назначить для проверки. Обратите внимание, что это моя первая попытка использования функций async / await. Может ли кто-нибудь указать, что мне здесь не хватает?

UPDATE: Поэтому после того, как я потратил целый день на ознакомление с концепциями обратных вызовов и обещаний, я нашел рабочее решение. Я предоставлю это как ответ ниже

1 Ответ

0 голосов
/ 26 апреля 2019

Я проверил SO и не смог найти решение этой проблемы.Так что, если кто-нибудь еще столкнется с этой проблемой, я предоставлю рабочее решение для этого.

Если вы хотите проверить поле по внешнему источнику данных, попробуйте следующее.Этот валидатор будет проверять адрес электронной почты, предоставленный для API (конечно, вы также можете использовать любой другой API), который проверяет, является ли адрес DEA, а также использовать ValidatorJS isEmail для проверки синтаксиса:

const YourSchema = new Schema({
// your fields
})

SchemaName.path('fieldNameToCheck').validate({
    validator: function(value) {

    return new Promise(function (resolve, reject) {

    request.get('https://disposable.debounce.io/?email=' + value, function (error, response, data) {

      if (error) reject(error);
      const content = JSON.parse(data);
      resolve((content.disposable === 'false' && isEmail(value)))  
    }
  });
 }
});

Ошибка, которую я сделал, состояла в том, что я попытался разрешить свое Обещание за пределами функции callback_ моего запроса.Но данные, которые я хочу использовать, очевидно, доступны только внутри них вовремя.

РЕДАКТИРОВАТЬ: для понимания вызова API.API возвращает JSON в виде {disposable: boolean}, если введенный адрес электронной почты принадлежит службе DEA (одноразовый адрес электронной почты)

...