Экспресс-валидатор - как обработать условную валидацию

У меня есть форма, в которой, если адрес доставки человека отличается от его адреса выставления счета, он выберет переключатель с надписью "нет".

Мне нужно иметь возможность проверить, каково значение этого, и если нет, проверить форму, которая разворачивается. если это "да", я перехожу к следующей проверке ниже. Раздел "да" работает, но раздел "нет" всегда возвращает недействительным. Есть ли способ вложить проверки в условное, как это с этой библиотекой?

Вот скриншот формы:

Образ тестовой формы

Вот код проверки, который у меня есть для этого сценария:

    router.post('/testData2/', [
      body('billingSameAsShipping', "Please Fill All Fields Of Your Billing Address").custom((value) => {
        if (value === 'no') {
          [
            body('billingFirstName', "Please Enter Your First Name").isLength({
              min: 1
            }),
            body('billingLastName', "Please Enter Your Last Name").isLength({
              min: 1
            }),
            body('billingAddress1', "Please Enter Your Billing Address").isLength({
              min: 1
            }),
            body('billingZip', "Please Enter Your Billing ZipCode").isLength({
              min: 1
            }),
            body('billingCity', "Please Enter Your Billing City").isLength({
              min: 1
            }),
            body('billingState', "Please Enter Your Billing State").isLength({
              min: 1
            })
          ]
        } else {

          return Promise.resolve();
        }

      }),
    body('creditCardNumber', 'Please Enter A Vaild Credit Card Number').isCreditCard(),
    body('expmonth', 'Exp Month Empty').isLength({
      min: 1
    }),
    body('expyear', 'Exp Year Empty').isLength({
      min: 1
    }),
    body('CVV', 'CVV Empty').isLength({
      min: 3
    })
  ],
  (req, res) => {...

Вот объект запроса, который мы проверяем

{
  billingSameAsShipping: 'no',
  billingFirstName: 'First',
  billingLastName: 'Last',
  billingAddress1: '450 Test Ave',
  billingZip: '12345',
  billingCity: 'San Diego',
  billingState: 'CA',
}

3 ответа

Решение

Я понял, Express Validator имеет встроенную условную проверку

Я использовал oneOf([]), чтобы проверить, было ли значение переключателей "да", или проверить, были ли заполнены поля адреса выставления счета.

router.post('/testData2/', [
    oneOf([
      [
        body('billingFirstName', "Please Enter Your First Name").isLength({
          min: 1
        }),
        body('billingLastName', "Please Enter Your Last Name").isLength({
          min: 1
        }),
        body('billingAddress1', "Please Enter Your Billing Address").isLength({
          min: 1
        }),
        body('billingZip', "Please Enter Your Billing ZipCode").isLength({
          min: 1
        }),
        body('billingCity', "Please Enter Your Billing City").isLength({
          min: 1
        }),
        body('billingState', "Please Enter Your Billing State").isLength({
          min: 1
        })
      ],
      body('billingSameAsShipping').equals('yes')
    ], "Please Fill Out All Fields Of Your Billing Address"),
    body('creditCardNumber', 'Please Enter A Vaild Credit Card Number').isCreditCard(),
    body('expmonth', 'Exp Month Empty').isLength({
      min: 1
    }),
    body('expyear', 'Exp Year Empty').isLength({
      min: 1
    }),
    body('CVV', 'CVV Empty').isLength({
      min: 3
    })
  ],
  (req, res) => {...

Кажется, сейчас это работает правильно.

У кого-нибудь есть какие-то другие решения для этого, или видите что-то не так с моим решением выше?

Вы также можете использовать это условие, которое позволяет делать такие вещи, как:

      body('billingFirstName').if(body('billingSameAsShipping').equals('yes')).notEmpty(),

и сорт

Есть более простой способ сделать валидаторы условными. Состояние - это boolean, так что вы можете просто использовать && логический оператор, чтобы решить, добавлять ли валидатор в массив или нет.

      router.post('/testData2/', [

   req.body.billingSameAsShipping && body('billingFirstName')
      .isLength({ min: 1 }),

   req.body.billingSameAsShipping && body('billingLastName')
      .isLength({ min: 1 })

   ].filter(x => !!x)
)

Фильтр в конце необходим, потому что, если условие оценивается, оно добавит falseв массив. Это вызовет ошибку времени выполнения, поэтому ее необходимо удалить. Это наиболее лаконичный способ условного добавления валидаторов.

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