мой массив изображений пуст, когда я передаю student действиям в redux, но он работает в postman

#reactjs #django #redux #django-rest-framework

#reactjs #django #redux #django-rest-framework

Вопрос:

Я пытаюсь добавить файлы изображений в массив изображений с помощью React, но получаю пустой массив изображений. Мой бэкэнд написан на Django. Он работает нормально, когда я использую postman для вставки файлов изображений, но я получаю пустой массив при использовании react. Вставка почтальона студента

AddNewStudent.js файл

 const AddNewStudent = () => {

  const [Name, setName]= useState('')
  const [Enrollment_No, setEnrollmentNo]= useState('')
  const [Registration_No, setRegistrationNo]= useState('')
  const [Semester, setSemester]= useState('')
  const [Year, setYear]= useState('')
  const [Course_Name, setCourseName]= useState('')
  const [Course_Code, setCourseCode]= useState('')
  const [studentImages, setStudentImages]= useState([])

  const dispatch= useDispatch()

  const submitForm= (e) => {
    e.preventDefault()
    const images=[]
    for (let image of studentImages){
      images.push({
        image
      })
    }
    console.log(images)
    
    const student={
      Name,
      Enrollment_No,
      Registration_No,
      Semester,
      Year,
      Course_Name,
      Course_Code, 
      images
      
    }
    
    
    console.log(student)
    dispatch(addStudent(student))

    


  }

  const handleStudentImages = (e) => {
    setStudentImages([
      ...studentImages,
      e.target.files[0]

    ])
  }




    return (
        <CCard>
            <CCardHeader>
              Add New Student
              
            </CCardHeader>
            <CCardBody>
              <CForm action="" method="post" onSubmit={submitForm}>
                <CFormGroup>
                  <CLabel htmlFor="nf-name">Name</CLabel>
                  <CInput type="text" id="nf-name" name="nf-name" placeholder="Name" autoComplete="name" onChange={(e) => setName(e.target.value)}/>
                  
                </CFormGroup>
                <CFormGroup row className="my-0">
                  <CCol xs="6">
                    <CFormGroup>
                    <CLabel htmlFor="nf-enrollmentno">Enrollment No</CLabel>
                  <CInput type="text" id="nf-enrollmentno" name="nf-enrollmentno" placeholder="Enrollment Number" autoComplete="enrollment_no" onChange={(e) => setEnrollmentNo(e.target.value)}/>
                  
                    </CFormGroup>
                    </CCol>
                    <CCol xs="6">
                    <CFormGroup>
                  <CLabel htmlFor="nf-registrationno">Registration No</CLabel>
                  <CInput type="text" id="nf-registrationno" name="nf-registrationno" placeholder="Registration Number" autoComplete="registration_no" onChange={(e) => setRegistrationNo(e.target.value)}/>
                  
                </CFormGroup>

                    </CCol>
                    </CFormGroup>
                   
            
                  

               
                <CFormGroup row className="my-0">
                <CCol xs="6">
                  <CFormGroup>
                  <CLabel htmlFor="select">Select Semester</CLabel>
                  <CSelect custom name="select" id="select" onChange={(e) => setSemester(e.target.value)}>
                      <option value="0">Please select</option>
                      <option value="1">Semester 1</option>
                      <option value="2">Semester 2</option>
                      <option value="3">Semester 3</option>
                      <option value="4">Semester 4</option>
                      <option value="5">Semester 5</option>
                      <option value="6">Semester 6</option>
                      <option value="7">Semester 7</option>
                      <option value="8">Semester 8</option>
                    </CSelect>
                  </CFormGroup>
                </CCol>
                <CCol xs="6">
                <CFormGroup>
                  <CLabel htmlFor="select">Select Year</CLabel>
                  <CSelect custom name="select" id="select" onChange={(e) => setYear(e.target.value)}>
                      <option value="0">Please select</option>
                      <option value="Fall 2020">Fall 2020</option>
                      <option value="Spring 2021">Spring 2021</option>
                      <option value="Fall 2021">Fall 2021</option>
                      <option value="Spring 2022">Spring 2022</option>
                    
                    </CSelect>
                  </CFormGroup>
                  </CCol>
                  </CFormGroup>
                  
                  
                  


              <CFormGroup row className="my-0">
                <CCol xs="6">
                <CFormGroup>
                  <CLabel htmlFor="select">Select Course Name</CLabel>
                  <CSelect custom name="select" id="select" onChange={(e) => setCourseName(e.target.value)}>
                      <option value="0">Please select</option>
                      <option value="DCN">DCN</option>
                      <option value="OOP">OOP</option>
                      <option value="DBMS">DBMS</option>
                      <option value="DSA">DSA</option>
                    
                    </CSelect>
                  </CFormGroup>
                </CCol>
                <CCol xs="6">
                <CFormGroup>
                  <CLabel htmlFor="select">Select Course Code</CLabel>
                  <CSelect custom name="select" id="select" onChange={(e) => setCourseCode(e.target.value)}>
                      <option value="0">Please select</option>
                      <option value="D1-101">D1-101</option>
                      <option value="ST-203">ST-203</option>
                      <option value="AD-567">AD-567</option>
                      <option value="TU-689">TU-689</option>
                    
                    </CSelect>
                  </CFormGroup>
                </CCol>
              </CFormGroup>
              <CFormGroup row>
                  <CCol md="3">
                    <CLabel>Add Images</CLabel>
                  </CCol>
                  <CCol xs="12" md="9">
                    <CInputFile 
                      id="file-multiple-input" 
                      name="file-multiple-input" 
                      multiple
                      custom
                      onChange={handleStudentImages}
                      
                    />
                    <CLabel htmlFor="file-multiple-input" variant="custom-file">
                    {
                        studentImages.length > 0 ? studentImages.map(img => {
                          return(
                            <span style={{paddingRight: 10}}>{img.name}</span>

                          )
                        }) : 'Add files...'
                    }
                    </CLabel>
                   
                   
                    
                  </CCol>
                </CFormGroup>
                <CCardFooter>
              <CButton type="submit" size="sm" color="primary"><CIcon name="cil-scrubber" /> Submit</CButton> <CButton type="reset" size="sm" color="danger"><CIcon name="cil-ban" /> Reset</CButton>
            </CCardFooter>
             
                
           
               
              </CForm>
            </CCardBody>
          
          </CCard>
    )
}

export default AddNewStudent

actions student.js 
export const addStudent = (form) => {
    return async (dispatch) => {
     
        dispatch({
            type: studentConstants.ADD_STUDENTS_REQUEST
        })

        try{
            const res= await axios.post(`/student/`, {
                ...form
            })
            console.log(res.data)

        }
        catch(error){
            console.log(error.response.data)
        }

    

        

    }
}
 

консоль напечатала studentЯ получаю изображения в виде файлов, когда печатаю student, но когда я передаю student в actions, массив изображений пуст

когда я передаю studentto actions массив изображений пуст

Комментарии:

1. Я думаю, вам может понадобиться упорядочить ваш form объект данных в формате JSON в вашем addStudent action creator.

2. привет, когда я это делаю, я получаю ошибки. {Name: Array(1), Enrollment_No: Array(1), Registration_No: Array(1), Year: Array(1), Course_Name: Array(1), …} Course_Code: [«Это поле обязательно».] Course_Name: [«Это поле обязательно».]Enrollment_No: [«Это поле обязательно».] Имя: [«Это поле обязательно».] Registration_No: [«Это поле обязательно».] Год: [«Это поле обязательно».] прото : объект e

3. Облом, извините. Вы подтвердили, что ваше studentImages состояние обновлено? Для этого вы можете использовать react-dev-tools. Когда действие отправляется, какова ценность form объекта? Это form.images то, чего вы ожидаете? Вы проверили вкладку network, чтобы убедиться, что ваш запрос POST верен? Вы сравнивали этот запрос с тем, который был сделан в Postman?

4. Возможно, вам потребуется установить multipart/form-data в качестве content-type (заголовок в запросе)

5. Большое вам спасибо @NadiaChibrikova. Наконец-то работает, я установил заголовки в соответствии с типом содержимого в моем запросе postman, и теперь это работает как шарм!

Ответ №1:

итак, я наконец-то заработал. что я сделал, так это изменил объект student на данные формы

     const form= new FormData();
    form.append('Name', Name)
    form.append('Enrollment_No', Enrollment_No);
    form.append('Registration_No',  Registration_No);
    form.append('Semester', Semester);
    form.append('Year', Year);
    form.append('Course_Name', Course_Name);
    form.append('Course_Code', Course_Code);
   
    
    for (let image of studentImages){

 
      
      form.append(`image_${image.name}`, image)
    }
 

а затем добавил хедеры содержимого в действие addStudent

   const headers= {
            "Content-Type": "multipart/form-data; boundary=<calculated when request is sent>"
            
        }

        try{
            const res= await axios.post(`/student/`, form, { headers: headers })
            console.log(res.data)

        }
 

и это работает!