Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ap3twe's avatar

AXIOS sending Request Twice

I send a POST request to a API server and the request sent 2 times. The initial request succeed because the records are inserted in the database then I get HTTP 500 response from the server. The Column CustomerID is a primary key and the request tries to send the request so it rejects it. I have attached the error response and added the payload request. In the forms I have deleted the some of the inputs to make it readable here.

Debug Console Preview Tab

resource: [{code: "23000",…}]
0: {code: "23000",…}
code: "23000"
message: "SQLSTATE[23000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Violation of PRIMARY KEY constraint 'PK_Customers'. Cannot insert duplicate key in object 'dbo.Customers'. The duplicate key value is (James-1520). (SQL: insert into [dbo].[Customers] ([CustomerID], [SalesPerson], [LabName], [CreatedBy], [Deleted]) values (James-1520, 0, 1, James, James, Dr, , Kwaku Clinic, 115 Ave, Toronto, AB, M5B 2P7, , Canada, 6833733, [email protected], More, 1, Prospects Form, 0))"
trace: [,…]
message: "Batch Error: Not all requested records could be created."
status_code: 500

Server Logs [2022-06-30T16:34:27.114490+00:00] local.INFO: [RESPONSE] {"Status Code":500,"Content-Type":null} [2022-06-30T16:34:27.115436+00:00] local.INFO: [RESPONSE] {"Status Code":200,"Content-Type":null}

**Example code ** Base URL

import axios from "axios";

const apiClient = axios.create({
  baseURL: "https://*****",
  headers: {
    "X-API-KEY":"8888********",
    "Content-Type": "application/json",
    Accept: "application/json",
    "access-control-allow-credentials": true,
    "access-control-allow-methods": "*",
    "access-control-allow-origin": "*",
    "access-control-allow-headers": "*",
    "cache-control": "no-cache",
    "cors-enabled": false,
  },
});

export default apiClient;
import apiClient from "./apiBaseUrl";
const addCustomers = "_table/Customers/";
const addProspects = (_prospect) => {
  const resource = JSON.stringify([
    {
      labID: _prospect.labID,
      LabName: _prospect.labName,
      // deleted the  following lines because they are not needed
      Deleted: _prospect.deleted,
    },
  ]);
  apiClient.post(
    addCustomers,
    resource
  
  );
  return apiClient.post(addCustomers, resource);
};

export default addProspects;

Form

/ Validation schema for the form
const validateSchema = Yup.object().shape({
  firstName: Yup.string().required().label("First Name"),
});

// Customer Id and Padding for the it
const strl = 30;
const initialNumber = 10;
const randomNumber = Math.floor(Math.random() * 100);
const custID = initialNumber + randomNumber + strl.toString().padStart(2, 3);

const Prospects = () => {
  // Function to handle the submit of the form
  const handleSubmit = async (values) => {
    const result = await apiEndPoints({
      ...values,
    });

    if (result.status >= 400 && result.status < 500) {
      console.log("400 Errors " + result.originalError);

    } else if (result.status >= 500) {

      console.log(result.config);
    } else if (result.problem) {

      console.log(result.config);
    } else {
      console.log("200 Success " + result.status);
    }
  };

  // Initial values for the form
  const initialValues = {
    active: false,
    prospect: true,
    customerID: custID,
    firstName: "",
 
  };

  return (
    <>

      <Layout>
        <div>
          <Formik
            initialValues={{
              ...initialValues,
            }}
            onSubmit={handleSubmit}
            validationSchema={validateSchema}
            enableReinitialize={true}
          >
            {({
              values,
              handleChange,
              handleBlur,
              handleSubmit,
            }) => (
              <form onSubmit={handleSubmit}>
                <Toast />
             
                  <div>
                    <label htmlFor="" className="relative block">
                      <span className="my-3"> Dr FirstName </span>
                      <input
                        type="text"
                        name="firstName"
                        id=""
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.firstName}
                      />
                    </label>
                  </div>
         
                <button
                  type="submit"
                  onClick={handleSubmit}
                >
                  Submit
                </button>
              </form>
            )}
          </Formik>
        </div>
      </Layout>
    </>
  );
};

export default Prospects;

Expected behavior

Expect only 1 request to be sent Response of 200

Environment

  • Axios Version [0.27.2]
  • Adapter [XHR/HTTP]
  • Browser [Chrome, Edge]
  • Browser Version [ Edge 103.0.1264.37 (Official build) (64-bit), Chrome 03.0.5060.66 (Official Build) (64-bit)]
  • Node.js Version
  • OS: [Windows 10]
  • React 18.0.1

Screenshots https://user-images.githubusercontent.com/37945729/176737595-c762f123-a99d-4b56-9955-850cb3bc2299.png

https://user-images.githubusercontent.com/37945729/176739117-ea07a722-c014-472b-a7ea-73f0bce7a6a4.png

https://user-images.githubusercontent.com/37945729/176739353-8cc8aaa1-c272-4ea4-9c79-ac62436b5e83.png

0 likes
16 replies
LaraBABA's avatar

Are you sure you are not doing something like:

1)You click on the form
2)The data goes to the API
3)A response comes back
4)The response data goes back into one of your form variable, which triggers a second  onChange={handleChange} event?

I think you are doing something like that. Follow all your code and see if the response data is not being refed into an onchange event which would then create a second loop with a 500 error(as you would have the same ID).

MohamedTammam's avatar

The problem is here

<button
type="submit"
onClick={handleSubmit}
>
	Submit
 </button>

When you click on that button you do two things, first you fire the default submit event which trigers the form onSubmit callback.

Then you fire the onClick event on the button with also execute the handleSubmit method. Thus to call that method 2 times.

I suggest to only fire handleSubmit on the form itself, because formik will not fire it unless it's valid (As Far As I Know).

<button type="submit">
	Submit
 </button>

Similar issue on StackOverflow: https://stackoverflow.com/q/61557815

Ap3twe's avatar

@MohamedTammam Removing the onClick={handleSubmit} from the button, I have a scope problem. <form onSubmit={handleSubmit}> does not see the delared function on top.

const handleSubmit = async (values) => {
    const result = await apiEndPoints({
      ...values,
    });
MohamedTammam's avatar

@Ap3twe Rename it to a different name than handleSubmit, and make sure that the form is valid (errors should be empty) before submitting.

MohamedTammam's avatar

@Ap3twe Is that how you code looks now?

const Prospects = () => {
  // Function to handle the submit of the form
  const submit= async (values) => {
    const result = await apiEndPoints({
      ...values,
    });
	
	// ..

  return (
    <>
      <Layout>
        <div>
          <Formik
            initialValues={{
              ...initialValues,
            }}
            onSubmit={submit}
            validationSchema={validateSchema}
            enableReinitialize={true}
          >
            {({
              values,
              errors,
              handleChange,
              handleBlur,
              handleSubmit,
            }) => (
              <form onSubmit={handleSubmit}>
				{ errors }
                // ..
                <button type="submit">
                  Submit
                </button>
              </form>
            )}
          </Formik>
        </div>
      </Layout>
    </>
  );
};

PS: I posted the part of the code that should be changed from the original post.

Ap3twe's avatar

@MohamedTammam thanks I feel like am getting there. I refactored the code to yours but I still get a second error after the success


  // Function to handle the submit of the form
  const submit = async (values) => {
    const result = await apiEndPoints({
      ...values,
    });

           <Formik
            initialValues={{
              ...initialValues,
            }}
            validationSchema={validateSchema}
            enableReinitialize={true}
            onSubmit={submit}
          >
            {({
              values,
              errors,
              touched,
              setFieldValue,
              handleChange,
              handleBlur,
              handleSubmit,
           //   isSubmitting,
            }) => (
              <form onSubmit={handleSubmit}>
                <button
                  // disabled={isSubmitting}
                  type="submit"
                >
                  Submit
                </button>
              </form>
            )}
          </Formik>
sirch's avatar

Are you posting the data twice by calling apiClient.post and then returning it?

const addProspects = (_prospect) => {
  const resource = JSON.stringify([
    {
      labID: _prospect.labID,
      LabName: _prospect.labName,
      // deleted the  following lines because they are not needed
      Deleted: _prospect.deleted,
    },
  ]);
  apiClient.post(
    addCustomers,
    resource
  
  );
  return apiClient.post(addCustomers, resource);
};
Ap3twe's avatar

@sirch I call it and return the response. is there something wrong? The addCustomers is the endpoint, and resource is the payload

sirch's avatar

@Ap3twe comment the first one out and see if you still send 2 requests. Your calling post on the axios object twice which may be your issue

Ap3twe's avatar
Ap3twe
OP
Best Answer
Level 5

I went with JS Fetch. It works by using Fetch API.

        fetch(
          "https://****/api/v2/" +
         Location +
            "/_table/monatablee/",
          requestOptions
        )
          .then((res) => {
            console.log(res);
            if (res.status === 200 || res.status < 300) {
              setIsLoading(false);
              toast.success("Prospect Added Successfully", {
                position: "top-center",
                autoClose: 5000,
              });

              setSalesValue({ salesPerson: "" });
              resetForm();
              submitEmail(values);
            } else {
              setIsLoading(false);
              toast.error("Something went wrong Error Code: " + res.status, {
                position: "top-center",
                autoClose: 5000,
              });
            }
          })
          .catch((err) => {
            setIsLoading(false);
            toast.error("Something went wrong", +err, {
              position: "top-center",
              autoClose: 5000,
            });
          });
      }, 10000);
    }

Please or to participate in this conversation.