How to add validation for status code 400 in react

Viewed 367

I am trying to edit a software program that requires a validation for an error on "Uncaught (in promise) Error: Request failed with status code 400"

Reason for this is that the user is trying to create a same unique data on the table. that is why it's getting a status code 400.

So now, I want to have a error handler for the status code 400 and will return a String in a text field stating "Duplicate Entry"

Here are my current validations.

    import * as Yup from "yup";

const InvoiceValidationSchema = Yup.object().shape({
  customer: Yup.object()
    .required("Customer is required."),
  invoiceDate: Yup.string()
    .required("Invoice Date is required"),
  dueDate: Yup.string()
    .required("Due Date is required."),
  invoiceNumber: Yup.string()
    .required("Invoice Number is required"),
  invoiceLines: Yup.array()
    .of(
      Yup.object().shape({
        product: Yup.object().required("Required"),
        quantity: Yup.number().required("Required.").min(1, "Quantity cannot be zero."),
        // price: Yup.number().required("Required.").min(1, "Quantity cannot be zero.").typeError("")
      })
    ).required("Required")
});

export default InvoiceValidationSchema;

I hope anyone can help me. Thanks

Here is the formik

<Formik
    validationSchema={InvoiceValidationSchema}
    initialValues={invoiceCrud}
    onSubmit={(values, action) => {

        const invoiceLines = values.invoiceLines.map(invoiceLine => {
            return {
                ...invoiceLine,
                product: invoiceLine.product,
                price: invoiceLine.price,
                quantity: invoiceLine.quantity,
                totalAmount: invoiceLine.quantity * invoiceLine.price,
                averagePurchasePrice: invoiceLine.product.averagePurchasePrice
            }
        })

        const subTotal = invoiceLines.reduce((sum, line) => {
            return sum + line.totalAmount;
        },0)

        const totalExpense = invoiceLines.reduce((sum, line) => {
            return sum + (line.product.averagePurchasePrice * line.quantity);
        },0)

        const totalAdjustment = 0;
        const netTotal = subTotal - totalAdjustment;

        const totalDueAmount = subTotal - values.subTotal + values.totalDueAmount;


        const invoice ={
            ...values,
            invoiceLines,
            subTotal,
            totalAdjustment,
            netTotal,
            totalExpense,
            totalDueAmount
        }

        if(values.invoiceLines[0].price > 0 && values.invoiceLines[0].quantity > 0){
            submit(invoice);
            setTimeout(() => {
                action.setSubmitting(false);
            }, 1000);
        }else{
            setIsZero(true)
            action.setSubmitting(false)
        }
    }}
    render={
        ({ values, errors, touched, setFieldValue, isSubmitting }) => (
             <Form>
                 <div className="box-body" id="invoice-crud">
                     <div className="row">
                         <div className="col-lg-3 col-md-6 col-sm-12">
                         {errors.invoiceLines ? setIsProductSelected(false) : null}
                         {errors.customer ? setCustomerClass("btn btn-default dropdown-toggle transaction-form__account has-error")
                             : setCustomerClass("btn btn-default dropdown-toggle transaction-form__account")}
                             <DropdownWithSearch
                                 property={
                                     {
                                         title: "Customer",
                                         buttonClass: CustomerClass,
                                         buttonLabel: values.customer ? values.customer.partnerName : "Select Customer",
                                         newButtonLabel: "Customer",
                                         showRemove: values.customer,
                                         modalSelector: "#partner-form"
                                     }
                                 }
                                 option={{
                                     list: partnerDetails.list,
                                     total: partnerDetails.total,
                                     currentPage: partnerDetails.currentPage,
                                     pageSize: partnerDetails.pageSize,
                                     load: changePartnerPage,
                                     display: (element) => element.partnerName,
                                     onClick: (element) => {
                                         setFieldValue("customer", element)
                                     },
                                     removeSelected: () => {
                                         setFieldValue("customer", null)
                                     },
                                     search: (search) => {
                                       dropdownSearch(search, "partner")
                                     }
                                 }}
                             />{errors.customer ? <span className="errorMessage">Please select a customer</span> : null}
                         </div>
                         <FormRow validation={{errors: errors, touched: touched}} field={invoiceNumber}/>
             </Form>
        )}
</Formik>
1 Answers

Question seems to be related to Formik and handling backend errors in it, rather than anything else.

You can check how to set manually backend errors in formik in this github issue.

And in particular this sandbox, posted by user @t-nunes in github.

If your function which makes the request is written in the new async/await style, you'll probably handle your errors in a try / catch block, and for the old .then, .catch style, you'll be using the .catch callback as long as server returns error code.

Related