form->bind($request) during ajax call outputs an array - symfony

I am posting a form with Ajax.
I have a surprising response when binding a form within an Ajax call:
public function newCartAjaxAction(Request $request)
{
$form = $this->container->get('new_cart_form.factory')->create();
$formHandler = $this->container->get('new_cart_form.handler');
if ('POST' === $request->getMethod())
{
$form->bind($request);
if ($form->isValid())
{
$formHandler->processValidForm($form);
$response = new Response();
$response->headers->set('Content-type', 'application/json; charset=utf-8');
$response->setContent(json_encode('hello'));
return $response;
}
//...
}
//....
}
Using firebug, I surprisingly obtain 3 outputs in the ajax Response:
array(2) {[0]=>int(3)[1]=>int(5)} //unexpected response
int(3) //unexpected response
"hello" //The only response needed
After debugging, I figured out that output 1 and 2 are from $form->bind($request);
Does anyone know why that is? I am very surprised to obtain a response from the form binding step as the only response that I am supposed to send is $response...
Have I done something wrong?

It's likely that these outputs were caused by code you've written.
First, make sure that your vendors are clean by reinstalling them.
Then, it could also be a form event listener/subscriber that you've written, so have also a look in this way.

Related

Status code 500 when deleting an object using axios and Symfony but deletion works

I'm using vue as my frontend. I want to delete an object from my database when a button is pressed, I post the selected object with axios but I get the following error:
wish.js:40 Error: Request failed with status code 500
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:61)
even though my object does get deleted from my database.
Here is my code:
postWishToBeDeleted({commit}, wishId) {
console.log(wishId);
axios.post('/api/post/delete', {
wishId: wishId
}).catch(error => {
console.error(error);
}).then( response => {
commit('removeWish', wishId);
}
)
}
Inside my symfony controller:
/**
* #Route("/api/post/delete", name="app_api_post_delete", methods={"POST"})
*/
public function deleteWish(Request $request, WishRepository $repository) {
$data = $request->getContent();
$data = json_decode($data, true);
$wish = $repository->find($data['wishId']);
$em = $this->getDoctrine()->getManager();
$em->remove($wish);
$em->flush();
return $this->json($wish);
}
I think that something with my response is wrong, I'm still new to Vue and axios so I'm not sure how return the json object correctly
EDIT:
I noticed that this error only occurs if I have more than one object?? If I it's only one and I delete it, there's no error
Status 500 is a server error, and it sounds from the behavior that whatever causes the error must happen after the item is removed.
Looking at the deleteWish method, if $wish has been removed, maybe the problem is trying to convert it to JSON when it's undefined. Try to return something else like:
return true;

Symfony2 Doctrine - Flushing in kernel.response listener flushs bad data

In order to do some logging for my Symfony2 app, I created a service that logs any connection, here is the method called on kernel.response :
public function log(FilterResponseEvent $event)
{
$log = new Log();
$request = $event->getRequest();
$response = $event->getResponse();
//fill the Log entity with stuff from request & response data
$manager = $this->container->get('doctrine.orm.entity_manager');
$manager->persist($log);
$manager->flush();
}
All of this seems fine, however when I execute a test like this one (patch with empty data to trigger a failure):
$this->client->request(
'PATCH',
'/users/testificate',
array(
'firstName' => '',
)
);
Which calls this action :
protected function processForm($item, $method = 'PATCH')
{
$form = $this->createForm(new $this->form(), $item, array('method' => $method));
$form->handleRequest($this->getRequest());
if ($form->isValid()) {
$response = new Response();
// Set the `Location` header only when creating new resources
if ($method == 'POST') {
$response->setStatusCode(201);
$response->headers->set('Location',
$this->generateUrl(
'get_' . strtolower($class), array('slug' => $item->getId()),
true // absolute
)
);
}
else {
$response->setStatusCode(204);
}
$this->em->flush();
return $response;
}
$this->em->detach($item);
return RestView::create($form, 400);
}
Although the test fails, the entity is patched, and of course it must not.
After some search what I've learnt is:
The parameters enter the form validator
The validation fails, thus returning a 400 http code without flushing the entity
However during the validation process, the entity gets hydrated with the invalid data
When the service is called on kernel.response, the $manager->flush(); flush all the data... including the bad data provided by the PATCH test.
What I've tried thus far:
1) Do a $manager->clear(); before $manager->persist(); ... doesn't change anything
2) Do a $manager->detach($item); if the form validation failed... doesn't change anything
Thanks !
I recently stumbled across problems with flushing in kernel.response when upgrading from Doctrine 2.3.4 to the latest 2.4 branch. Try flusing the log entities from kernel.terminate. Leave any modifications to the Response in kernel.response.

Symfony2 request called twice

I have a problem with Symfony2 duplicating requests.
The example controller below should just return a transparent gif. However, when the URL is requested there are two 'hits' to the request and doSomething() is called twice instead of once.
// simple action in a controller, ends up being called twice
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
$response->headers->set('Content-Type', 'image/gif');
return $response;
}
If I change the response line so it sets a blank response then this stops happening (i.e. doSomething() is only called once):
// with a blank response it is only called once
public function testAction() {
doSomething();
$response = new Response('');
$response->headers->set('Content-Type', 'image/gif');
return $response;
}
If I remove the headers line then it's only called once:
// without the Content-Type header it is only called once
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
return $response;
}
Finally (here's the punchline)... if I change the Content-Type to text/html (or text/css) then it is only called once!
// if a text content type is used, it is only called once
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
$response->headers->set('Content-Type', 'text/html');
return $response;
}
But with real content and the proper headers it is called twice (and two identical looking entries appear in the web profiler). The same problem also happens if a php template is used to render the content (I haven't tried with twig).
What could be causing this and how can it be prevented (or worked around)?
Edit: So, in summary, it was a Firefox bug and nothing to do with Symfony at all.

Getting POST request on Symfony2

I've been looking for this and any of the answers work for me:
I'm using this to get the POST request:
$request = Request::createFromGlobals();
$order = $request->query->get('Ds_Order');
But Order is never has a value, even though the name is correct. If I do a GET request that value exists.
This is the var_dump of $request
object(Symfony\Component\HttpFoundation\Request)#841 (18) {
["attributes"]=>
object(Symfony\Component\HttpFoundation\ParameterBag)#838 (1) {
["parameters":protected]=>
array(0) {
}
}
["request"]=>
object(Symfony\Component\HttpFoundation\ParameterBag)#840 (1) {
["parameters":protected]=>
array(15) {
["Ds_Date"]=>
string(10) "10/10/2012"
["Ds_Hour"]=>
string(5) "14:31"
["Ds_Currency"]=>
string(3) "978"
["Ds_Order"]=>
string(4) "0026"
}
}
}
Does anyone know how to access the attributes that are being sent to me?
Thanks.
To retrieve a POST request parameter you've to use
$order = $request->request->get('Ds_Order');
Read Requests and Responses in Symfony
// retrieve GET variables
$request->query->get('foo');
// retrieve POST variables
$request->request->get('bar', 'default value if bar does not exist');

symfony 2 error - persisting data to a database

I get a message : "Oops! An Error Occurred
The server returned a "500 Internal Server Error".
Something is broken. Please e-mail us at [email] and let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused" when persisting data to a database. Here is a controller:
public function registerAction()
{
$register = new Register();
$form = $this->createForm(new RegisterType(), $register);
$request = $this->getRequest();
if ($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getEntityManager();
$em->persist($register);
$em->flush();
return $this->redirect($this->generateUrl('ShopMyShopBundle_register'));
}
}
return $this->render('ShopMyShopBundle:Main:register.html.twig', array('form' => $form->createView()));
}
Where is the problem ?
The code you provided is not enough to find the reason. You should develop using the dev environment to see detailed error messages. To do it, access your app with the app_dev.php front controller. See the section on environments.

Resources