How to update state in onSubmit form & send data through components?

Viewed 50

I have a state which I need to update with the ID returned from an endpoint call so I can call another another endpoint using that ID, I've made a state in the parent component and I use it in my first form to set the ID. I pass that id as a prop to the component that needs it but when I console.log the state, it doesn't change.

How can I pass the ID through the components?

I've added comments on the main places to look at

Here is my first form where I need the ID from -

const AddWebAppTypeForm = (props: any, ref: any) => {
  const { setWebAppTypes, setNewAppValues}: AddWebAppTypeFormProps =
    props;
  const {
    handleSubmit,
    control,
    reset,
    formState: { isDirty },
  } = useForm();


  const onSubmit = (data: any) => {
    let formData = new FormData();
    formData.append("name", data.Title);
    formData.append("description", data.Description);
    formData.append("uploaded_file", data.Image[0]);

    if (isDirty) {
      createWebAppType(formData);
    }
  };

  const createWebAppType = async (body: any) => {
    await fetch(`${process.env.REACT_APP_API_URL}/webapptype`, {
      method: "POST",
      body: body,
    })
      .then((response) => response.json())
      .then((data: IWebAppType) => {
        const model: IWebAppType = {
          id: data.id,
          name: data.name,
          image: data.image,
          description: data.description,
          image_url: data.image_url,
        };
        setNewAppValues(model.id); // <--- Set the state here
        setWebAppTypes((prev) =>
          prev.map((item) => (item.id === 0 ? model : item))
        );
        enqueueSnackbar(`Created App Succesfully`, {
          variant: "success",
        });
      });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <button hidden={true} ref={ref} type="submit" />
    </form>
  );
};

export default forwardRef(AddWebAppTypeForm);

My parent component with the states -

function WebAppTypeAccordion({ a, setWebAppTypes }: WebAppTypeAccordionProps) {
  const [formEl, setFormEl] = useState(null);
  const [addFormEl, setAddFormEl] = useState(null);
  const [newAppValues, setNewAppValues] = useState<number>(0); // <--- state with 0 as initialised value

  const handleRef = (el: any) => {
    if (el !== null) {
      setFormEl(el);
    }
  };

  const handleAddRef = (el: any) => {
    if (el !== null) {
      setAddFormEl(el);
    }
  };
  return (
    <Accordion defaultExpanded={a.id === 0}>
      <AccordionSummary
        // onClick={(e) => handleOnClick(a, e)}
        expandIcon={<ExpandMoreIcon />}
        aria-controls="panel1a-content"
        id="panel1a-header"
      >
        <Typography>{a.name}</Typography>
      </AccordionSummary>
      <AccordionDetails>
        {a.id === 0 ? (
          <AddWebAppTypeForm
            setWebAppTypes={setWebAppTypes}
            ref={handleAddRef}
            setNewAppValues={setNewAppValues} // <--- Passing setState to set id
          />
        ) : (
          null
        )}

        <MappedAccordion
          waobj={a}
          key={a.id}
          setWebAppTypes={setWebAppTypes}
          editRef={formEl}
          addRef={addFormEl}
          newAppValues={newAppValues} // <--- Passing ID
        />
      </AccordionDetails>
    </Accordion>
  );
}

export default WebAppTypeAccordion;

Here is where I am trying to use the ID to call another endpoint

function MappedAccordion({
  waobj,
  setWebAppTypes,
  editRef,
  addRef,
  newAppValues,
}: MappedAccordionProps) {

  
  const handleCreate = (data: FieldT) => {
    let wtype: string = String(waobj.id);
    if (addRef !== null) {
      if (newAppValues !== 0) {
        wtype = String(newAppValues); // <--- Try to use the ID but get default value
        createFetch(data, wtype); // <--- Try to use the ID but get default value
      }
    }
    createFetch(data, wtype);
  };

  const createFetch = (data: FieldT, wtype: string) => {
    let formData = new FormData();
    formData.append("name", data.name);
    formData.append("link", data.link);
    formData.append("wtype", wtype);

    fetch(`${process.env.REACT_APP_API_URL}/webapp/`, {
      method: "POST",
      body: formData,
    })
      .then((response) => {
        if (!response.ok) {
          let err = new Error("HTTP status code: " + response.status);
          enqueueSnackbar(`Environment already exists`, {
            variant: "error",
          });
          throw err;
        }
        return response.json();
      })
      .then((data: IWebApp) => {
        const model: FieldT = {
          wid: data.id,
          name: data.name,
          link: data.link,
        };
        enqueueSnackbar(`Created Environment ${model.wid}`, {
          variant: "success",
        });
      });
  };

  const onSubmit = (data: FormFields) => {
    if (addRef !== null) addRef?.click(); // <--- Submit AddWebAppTypeForm form, set the ID
    else editRef?.click();

    let onSubmitData: FieldT[] = data.myFieldValues;
    onSubmitData.map((a: FieldT, index) => {
      let originalField: FieldT = initialFields[index];
      if (a.wid === undefined) {
        handleCreate(a);
      } else {
        if (JSON.stringify(a) !== JSON.stringify(originalField)) {
          handleEdit(a);
        }
      }
    });
  };

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)} id="environment-form">
        <div style={{ paddingTop: 10 }}>
          <Button
            type="submit"    // <--- Submit form
            variant="outlined"
            size="small"
            sx={{ marginRight: 1 }}
          >
            Save
          </Button>
          <Button
            variant="outlined"
            size="small"
            onClick={handleAppDelete}
            disabled={waobj.id === 0 ? true : false}
          >
            Delete
          </Button>
        </div>
      </form>
    </div>
  );
}

export default MappedAccordion;

Thanks for taking a look, I appreciate any help!

0 Answers
Related