I have this error when I refresh page content form then persistent object.
code handler: content function post when I create form with handle :
public function post(array $parameters, bool $submitted = false, array $options = [])
{
$recruiter = $this->formHandler->handle(
$this->factory->create(),
$parameters,
Request::METHOD_POST,
$submitted,
$options
);
if ($recruiter instanceof Recruiter) {
$this->repository->save($recruiter);
return $recruiter;
}
}
code controller: use function post for handler and I use try and catch:
/**
* @Template()
* @Route("/register", name="register_recruiter")
*
* @param Request $request
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function registerAction(Request $request)
{
try {
$quiz = $this->getHandler()->post($request->request->all());
return $this->redirectToRoute('recruiter_quizs_index');
}
catch (InvalidFormException $e) {
return [
'form' => $e->getForm()->createView(),
'edit' => false,
];
}
code twig content form :
{{ form(form) }}
function handle for create form:
public function handle($object, array $parameters, string $method, bool $submited = false, array $options = [])
{
$options = array_replace_recursive([
'method' => $method,
'csrf_protection' => false,
], $options);
$form = $this->formFactory->create(get_class($this->formType), $object, $options);
if (!$submited) {
throw new InvalidFormException($form);
}
$form->submit($parameters, 'PATCH' !== $method);
if (!$form->isValid()) {
throw new InvalidFormException($form);
}
return $form->getData();
}
The problem is that you do not provide a value for the 2nd parameter $submitted
, which should probably be true
if the method is POST, PUT or PATCH.
The easy way to fix this is checking for the method in the action and provide the boolean parameter
/**
* @Template()
* @Route("/register", name="register_recruiter")
*
* @param Request $request
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function registerAction(Request $request)
{
try {
$submitted = ($request->isMethod('PATCH') || $request->isMethod('POST') || $request->isMethod('PUT'));
$quiz = $this->getHandler()->post($request->request->all(), $submitted);
return $this->redirectToRoute('recruiter_quizs_index');
}
catch (InvalidFormException $e) {
return [
'form' => $e->getForm()->createView(),
'edit' => false,
];
}
Although I think this is a really bad solution. You should create an action for each HTTP method. Show the form with GET, submit it with POST/PUT/PATCH. Put the submit route before the GET route, so it will match first:
/**
* submit the recruiter form (on PATH, POST, PUT)
*
* @Template()
* @Route("/register", name="register_recruiter_submit", methods={"PATCH","POST","PUT"})
*
* @param Request $request
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function registerSubmitAction(Request $request)
{
try {
$quiz = $this->getHandler()->post($request->request->all(), true);
return $this->redirectToRoute('recruiter_quizs_index');
}
catch (InvalidFormException $e) {
return [
'form' => $e->getForm()->createView(),
'edit' => false,
];
}
}
/**
* show the recruiter form (route will match if method is not PATCH/PUT/POST
*
* @Template()
* @Route("/register", name="register_recruiter_form")
*
* @param Request $request
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function registerFormAction(Request $request)
{
return [
'form' => $this->formHandler->createView(),
'edit' => false,
];
}