0

I block for 2 days for uploading an image. I have a form with some stuff like date, string, bool, and image. It's for creating an announcement on my website.

We actually use: Reactjs, Redux, Axios, Datepicker

There is my code : (sorry if it's crap, I'm beginning code...)

Component (for the img) :

<form id="myform" onSubmit={onCreateAnnouncementSubmit} method="post" >
{...}

<div className="createAnnouncement__input drop desktop input">
          <input 
            type="file" 
            className="input" 
            accept=".png, .jpg, .jpeg" 
            name={picture}
            onChange={fileChangedHandler}  
          />
</div>
{...}
<div className="createAnnouncement__flex">
        <button type="submit" className="createAnnouncement__button button">Créer</button>
</div>

Container :

import CreateAnnouncement from '../components/CreateAnnouncement';
import { inputCreateAnnouncement,  postCreateAnnouncement, passId} from '../Redux/actions'
import {connect} from 'react-redux';

const mapStateToProps = ({data}) => {
  return({
   {...}
    picture: data.create.picture,    
  })
};

const mapDispatchToProps = (dispatch, {match}) => ({

  onCreateAnnouncementSubmit: (e) => {e.preventDefault(); dispatch(passId(postCreateAnnouncement))},

  fileChangedHandler = (event) => dispatch(inputCreateAnnouncement({ [e.target.name]: {
    selectedFile: event.target.files[0]
  }})),

})
;

const createAnnouncement = connect(mapStateToProps, mapDispatchToProps)(CreateAnnouncement);

export default createAnnouncement;

Here some actions :

export const INPUT_CREATE_ANNOUNCEMENT= 'INPUT_CREATE_ANNOUNCEMENT';

export const inputCreateAnnouncement = (payload) => ({
  type: INPUT_CREATE_ANNOUNCEMENT,
  payload
})


export const postCreateAnnouncement = () => (dispatch, getState) => {
  const fd = new FormData();
  fd.append('image', selectedFile)
  axios({
    headers: {      
      ContentType: 'multipart/form-data',
      Authorization: `bearer ${token()}`,
    },
    method: 'post',
    url: `***********/api/announcements/`, 
    data: 
    {             
      user_id: getState().login.userId,
      category: "default",      
      ...getState().data.create          
    }
  })
  .then((res) => console.log(res))
  .catch((err) => console.log(err))
};

export const passId = (func) => (dispatch, getState) => {
  dispatch(func(getState().login.userId))
}

And the data :

const initialState = {
  create: {
 {...}
    picture: null,     
  },

{...}

case INPUT_CREATE_ANNOUNCEMENT:
      return {
        ...state,
        create:{...state.announcements[0], ...action.payload}
      }

In my symfony :

/**
     * @Route("/", name="add", methods={"POST"})
     */
    public function add(Request $request, GetErrorsFromForm $getErrorsFromForm)
    {
        $announcement = new Announcement();
        // On décode les données envoyées
        $donnees = json_decode($request->getContent(), true);
        /** On verifie si la propriété est envoyé dans le json si oui on hydrate l'objet 
         * sinon on passe à la suite */
        $form = $this->createForm(AnnouncementType::class, $announcement);
        $form->submit($donnees);
        $donnees = json_decode($request->getContent(), true);
        $form = $this->createForm(AnnouncementType::class, $announcement);
        //dd($announcement);
        $form->submit($donnees, false);
        if ($form->isValid()) {
            $announcement->setCreatedAt(new \DateTime);
            if ($form['picture']->isSubmitted() && $form['picture']->isValid()){
            /** @var UploadImage 
             * $uploadedFile */

            $uploadedFile = $form['picture']->getData();
            $destination = $this->getParameter('kernel.project_dir').'/public/uploads/AnnouncementPicture';
            $originalFilename = pathinfo($uploadedFile->getClientOriginalName(), PATHINFO_FILENAME);
            $newFilename = $originalFilename.'-'.uniqid().'.'.$uploadedFile->guessExtension();
            $uploadedFile->move(
                $destination,
                $newFilename
            );}
            $em = $this->getDoctrine()->getManager();
            $em->persist($announcement);
            $em->flush();
            return new JsonResponse('ok', 201);
        } else {
            $errors = $getErrorsFromForm->getErrors($form);
            $data = [
                'type' => 'validation_error',
                'title' => 'There was a validation error',
                'errors' => $errors,
            ];
            return new JsonResponse($data, 400);
        }
    }

Thanks in advance and sorry for my bad English...

1 Answers1

0

you can send your form information with axios using FormData like this:

  const firstName = 'my_first_name';
  const lastName = 'my_last_name';
  const date = '2020-04-10';// date in format that your backend supports
  const fd = new FormData();
  fd.append('name', firstName)
  fd.append('last_name', lastName);
  fd.append('file', selectedFile);
  fd.append('date', date);
  axios({
    headers: {      
      ContentType: 'multipart/form-data',
      Authorization: `bearer ${token()}`,
    },
    method: 'post',
    url: `***********/api/announcements/`, 
    data: fd

  })
  .then((res) => console.log(res))
  .catch((err) => console.log(err))

you can read more :
axios post request to send form data
axios - send form data AND non-form data

Shahab Emami
  • 324
  • 1
  • 7