1

I have a Curriculum Vitae form that does not send the data unless two sections are completely filled. For testing purposes none of the fields are required. Furthermore I am getting the error:

POST http://localhost:8000/api/jobApplications net::ERR_CONNECTION_RESET

The issue is because there are 2 sections in the CV, Education and Work Experience, that have aggregate fields when clicking on a button that adds a new Education/Work field row. If all these fields within these rows aren't filled, it will not send.

The input fields' name and value in the Education and Work sections have a functionality where when you click on add new row of fields, it will replace/change the letter in both the input name and value.

Here are the useState hooks:

const [inputValue, setInputValue] = useState<JobApplicationInterface>(JobApplicationForm);
const [divEducationList, setDivEducationList] = useState<number[]>([]);
const [divWorkList, setDivWorkList] = useState<number[]>([]);
const [divEducation, setDivEducation] = useState<number>(0);
const [divWork, setDivWork] = useState<number>(0);
const [arrayEducation, setArrayEducation] = useState<ArrayLettersInterface[]>(arrayLetters);
const [arrayWork, setArrayWork] = useState<ArrayLettersInterface[]>(arrayLetters);

Here's the Education section (the Work Experience section is basically the same, except has the option to add more fields - Education is limited at 3 rows of fields and Work is limited to 5).

EDUCATION SECTION
<div className='input-group-container education-container'>
    <div className='input-group education-group'>
        <div className='input-container input-wrapper'>
            <Select
                title='Education Degree'
                name='education_a_degree'
                value={inputValue.education_a_degree}
                optionList={degreeSelectOptionArray}
                handleSelect={handleSelect}
            />
        </div>
        <div className='input-container input-wrapper'>
            <Input
                title='University'
                type='text'
                value={inputValue.education_a_school}
                name='education_a_school'
                handleInput={handleInput}
            />
        </div>
        ...MORE INPUTS (type=text)...
        <div className='btn-group-container education-btns'>
            <Button
                btnTitle={<Add />}
                handleClick={handleClickAddEducation}
            />
        </div>
    </div>
    {divEducationList.map((_, index: number) => (
        <div className='input-group education-group' key={index}>
            <div className='input-container input-wrapper'>
                <Select
                    title='Education Degree'
                    value={inputValue[`education_${arrayLetters[index].letter}_degree`]}
                    name={`education_${arrayLetters[index].letter}_degree`}
                    optionList={degreeSelectOptionArray}
                    handleSelect={handleSelect}
                />
            </div>
        <div className='input-container input-wrapper'>
            <Input
                title='University'
                type='text'
                value={inputValue[`education_${arrayLetters[index].letter}_school`]}
                name={`education_${arrayLetters[index].letter}_school`}
                handleInput={handleInput}
            />
        </div>
        ...MORE INPUTS (type=text)...
        <div className='btn-group-container education-btns'>
            {!divEducationList?.[1] ? (
                <Button
                    btnTitle={<Add />}
                    handleClick={handleClickAddEducation}
                />
             ) : null}
             <Button
                 btnTitle={<Remove />}
                 handleClick={(event: React.ChangeEvent<HTMLInputElement>) =>
                        handleClickRemove(event, index, 'education')
                 }
             />
        </div>
    </div>
    ))}
</div>

I have 2 functions for adding a new row of fields, one for Education and the other for Work, and they are the same. This function also adds a new letter ('a', 'b', 'c',...) to all of the row's input names and values each time a new row is added.

HANDLECLICKS
const handleClickAddEducation = () => {
    if (divEducationList.length < 2) {
        for (let i = 0; i < divEducationList.length; i++) {
            if (arrayLetters[i].index === i) {
                setArrayEducation((prev: any) => ({
                    ...prev,
                    [i]: arrayLetters[i].letter,
                }));
            }
        }
        setDivEducation((divEducation: number) => divEducation + 1);
        return setDivEducationList((divEducationList: any) => [
            ...divEducationList,
            divEducation,
        ]);
    } else {
        throw new Error('too many selected');
    }
};

const handleClickAddWork = () => {
    if (divWorkList.length < 2) {
        for (let i = 0; i < divWorkList.length; i++) {
            if (arrayLetters[i].index === i) {
                setArrayWork((prev: any) => ({
                    ...prev,
                    [i]: arrayLetters[i].letter,
                }));
            }
        }
        setDivWork((divWork: number) => divWork + 1);
        return setDivWorkList((divWorkList: any) => [
            ...divWorkList,
            divWork,
        ]);
    } else {
        throw new Error('too many selected');
    }
};

This is the handle input:

HANDLEINPUTS
const handleInput: React.ChangeEventHandler<HTMLInputElement> | undefined = (
    event: React.ChangeEvent<HTMLInputElement>
) => {
    const value = event.target.value;
    const name = event.target.name;
    setInputValue((prev) => ({ ...prev, [name]: value }));
};

For the POST request I use Axios and FormData, and submitting to the server is not an issue, unless, as mentioned above, Education/Work sections are not completely filled.

HANDLESUBMIT
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (
    event: React.FormEvent<HTMLFormElement>
) => {
    event.preventDefault();
    setIsLoading(true);

    let keys = Object.keys(inputValue);
    let values = Object.values(inputValue);
    for (let i = 0; i < keys.length; i++) {
        formData.append(keys[i], values[i] as unknown as Blob);
    }

    axios
        .post(postApiUrl, formData, postHeaders)
        .then((response) => {
            console.log(response.data);
        })
        .catch((err) => {
            const error =
                err.code === 'ECONNABORTED'
                    ? 'A timeout has occurred'
                    : err.response.status === 404
                    ? 'Resource not found'
                    : 'An unexpected error has occurred';
            setError(error);
            setIsLoading(false);
        })
        .finally(() => setIsLoading(false));
};

If you require more information, please let me know, thanks!

FlyingR
  • 23
  • 4

0 Answers0