Как использовать динамическую переменную в статической схеме yup?

Я хочу статически создать схему yup (схема определяется один раз), которая принимает динамическую переменную каждый раз, когда она вызывается (переменная может отличаться при каждом вызове). Это возможно?

например.,

// file: schema.js
// create the schema once
yup = require('yup');
const schema = yup.mixed().test(
  'my-test-name',
  'cannot be an existing value',
  value => !myArray.includes(value)  // How to reference myArray here?
       // As written, it results in "ReferenceError: myArray is not defined"
);
module.exports = schema;



// other file that imports the schema:
schema = require('./schema.js');
let myArray = ['blue', 'green'];
schema.validateSync('yellow');  // should pass validation, because 'yellow' not in myArray

myArray = ['orange', 'yellow'];
schema.validateSync('yellow');  // should fail validation, because 'yellow' is in myArray

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
9 296
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте экспортировать функцию, которая создает динамическую схему. См. Ниже.

// file: schema.js
// create the schema once
yup = require('yup');

// export as a function
module.exports = myArray => {
  return yup.mixed().test(
    'my-test-name',
    'cannot be an existing value',
    value => !myArray.includes(value)  
  );
};



// other file that imports the schema:
schema = require('./schema.js');
let myArray = ['blue', 'green'];

let blueGreenSchema = schema(myArray);
blueGreenSchema.validateSync('yellow');  

myArray = ['orange', 'yellow'];
let orangeYellowSchema = schema(myArray);
orangeYellowSchema.validateSync('yellow');  

Да, я понимаю, что это альтернатива. Однако я работаю с кодовой базой со многими статически определенными схемами «да» с сопоставлением с соответствующими полями. Я надеюсь найти способ иметь возможность использовать динамические переменные только для пары тех схем, которые в них нуждаются, и не изменять каждую статическую схему, чтобы она была динамической.

Rob Bednark 10.10.2018 16:47
Ответ принят как подходящий

Чтобы использовать динамическую переменную, необходимы 3 вещи:

  1. используйте второй параметр Options для validateSync() с ключом context
  2. объявить функцию .test(), используя выражение функции, а не функцию стрелки (потому что да, функция связывает функцию с this)
  3. внутри тестовой функции укажите динамическую переменную с помощью this.options.context.variableName

например.,

const yup = require('yup');

// statically declare the schema
const schema = yup.mixed().test(
  'my-test-name',
  'cannot be an existing value',  // error message
  function test(value) {
    // NOTE: this must not be an arrow function, because yup binds it to it's "this"
    // Note the use of this.options.context to reference the dynamic variable
    return !this.options.context.myArray.includes(value)  
  }
);

// Note the use of passing a { context: ... } as the second "options" parameter to validateSync()
ret = schema.validateSync('yellow', { context: { myArray: ['blue', 'green'] } } );
console.assert(ret === 'yellow');  // passes validation

    let errorMessage;
try {
  schema.validateSync('blue', { context: { myArray: ['blue', 'green'] } } );
}
catch(error) {
  errorMessage = error.message;
}
console.assert(errorMessage === 'cannot be an existing value');

Другие вопросы по теме