0
votes

I've a function in my Symfony2 controller called through Ajax from the view. This is the code on the controller side (a example not the real):

public function addFabAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $response['success'] = TRUE;

    if ($request->isXmlHttpRequest()) {
        $entity = new Entity();
        $form = $this->createForm(new EntityForm(), $entity);
        $form->handleRequest($request);

        if ($form->isValid()) {
            try {
                $em->persist($entity);
                $em->flush();

                $response['entities'] = array();
                $dataResponse = array();
                $dataResponse['colOne'] = $$entity->getColumnOne();
                $dataResponse['colTwo'] = $$entity->getColumnTwo();

                $response['entities'][] = $dataResponse;
            } catch (Exception $ex) {
                $response['success'] = FALSE;
            }
        } else {
            // Response for go through .fail() callback in Ajax request 
        }

        return new JsonResponse($response);
    }
}

Then in the view I call on some event as follow:

$.post(Routing.generate('addFab'), $form.serialize(), 'json').done(function (data, textStatus, jqXHR) {
    // if all goes fine then show messages and much more
    }
}).fail(function () {
   // if something goes wrong then show and alert and try to show info to the user 
    return false;
}).always();

Now if $form->isValid() is TRUE or not the request always be made and therefore will go through .done() callback so I need to return something, not clear what, if form isn't valid so response goes through .fail() callback, otherwise I'll always need to check if, for example, $response['success'] is TRUE or FALSE in the .done() callback and forget about the .fail() which seem wrong to me. I don't now if the right way is to return an exception using the HttpFoundation Componente or something else so any advice? What's the best way to get ride of this?

3
check what is the reason for the error fail(function (jqXHR, status, error) { alert(status+':' + error) // if something goes wrong then show and alert and try to show info to the user return false; }) - it could be that the response is not properly formatted and you are getting a parse errorArun P Johny
@ArunPJohny maybe my question is not good at all, what I mean is I need to response something from my controller for any failure not just form validation but other examples could be invalid form credentials, duplicate fields on DB and something else, did you get it now?ReynierPM
in that case you need to set the response state to something like 400 or any other error states.. may be something like <?php http_response_code(400); ?>Arun P Johny

3 Answers

2
votes

The error handler is called when the server returns an error status like 4xx or 5xx or when there is a client side parsing error of the returned data or when there is a abort call on the request.

In this case since based on a validation you want to sent the request to the failure handler you need to set the response status to an error state like 400. So in your else block try

<?php
http_response_code(400);
?>
1
votes

I know this has been answered but I don't think it's the best way of going.

The JsonResponse object takes a status code as the second parameter so rather than sticking a http_response_code in your code you should add the status code into that.

Also rather than defaulting your success to true it would make more sense to default it to false and then update it in a success.

You could do this like..

public function addFabAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $response['success'] = false;
    $status = null;

    if ($request->isXmlHttpRequest()) {
        $entity = new Entity();
        $form = $this->createForm(new EntityForm(), $entity);
        $form->handleRequest($request);

        if ($form->isValid()) {
            try {
                $em->persist($entity);
                $em->flush();

                $response['entities'] = array();
                $dataResponse = array();
                $dataResponse['colOne'] = $entity->getColumnOne();
                $dataResponse['colTwo'] = $entity->getColumnTwo();

                $response['entities'][] = $dataResponse;

                $response['success'] = true;
            } catch (Exception $ex) {
                $status = 400; // Your error code
                $response['error_message'] = 'something';
            }
        } else {
            $status = 400;
            $response['error_message'] = 'form not valid';
        }

        return new JsonResponse($response, $status ?: 200);
    }
}

Also you have no response if the request wasn't an XmlHttpRequest but that may be handled elsewhere, obviously.

0
votes

I would not be surprised if I'm missing something here as I don't use $.post, I do use $.ajax which I would guess is nearly the same. If I'm right here, the .fail is when the server response with an IIS error and should not be used for form validation. That should be done in your application logic which would make it right to be handled in the .done. If I'm needing to return a negative response without details then I would return "false" otherwise a populated json result.