ReynierPM
ReynierPM

Reputation: 18660

Redirect does not work when method/route is called trough AJAX request

I have this code on listDevice.html.twig template.

$.ajax({
    type: "GET",
    url: "http://dev/app_dev.php/device/" + window.id + "/remove",
    crossDomain: false,
    dataType: "html",
    error: function(data) {
        console.log("Error in Processing-----" + data.status);
    }
});

The code is triggered when someone click on delete button (doesn't matter). And this is the function that handle the deletion at DeleteController.php:

/**
 * @Route("/device/{id}/remove",  name="device_remove")
 * @param integer $id
 * @param Request $request
 * @Method({"GET"})
 * @Template()
 * @Security("has_role('ROLE_ADMIN')")
 * @return array
 */
public function removeAction(Request $request, $id = null)
{
    $em = $this->getDoctrine()->getManager();
    $can_delete = $em->getRepository('DeviceBundle:UnassignedDevices')->findBy(array('id' => $id));

    if (count($can_delete) == 0) {
        $driverHasDevice = $em->getRepository("DeviceBundle:DriverHasDevice")->findOneBy(array('device' => $id));
        $deviceToRemove = $em->getRepository("DeviceBundle:Device")->findOneBy(array('id' => $id));

        if ($driverHasDevice) {
            $em->remove($driverHasDevice);
        }

        $em->remove($deviceToRemove);
        $em->flush();

        $flashMessage = $this->get('translator')->trans('delete.success', array('%element%' => 'device'));
    }
    else {
        $flashMessage = $this->get('translator')->trans('devices.messages.driver.assigned');
    }

    $this->get('session')->getFlashBag()->add('message', $flashMessage);
    return $this->redirect($this->generateUrl('device_list'));
}

Both works fine, I mean when I click on delete button the route matches and the code is executed but the redirect, this line, $this->redirect($this->generateUrl('device_list')); never happen, why is that? How I can fix this?

Upvotes: 2

Views: 3297

Answers (2)

Tomasz Madeyski
Tomasz Madeyski

Reputation: 10890

What $this->redirect does is basically returning response with 302 http status, which is redirect. This won't be parsed by ajax call (it waits for 200 OK status) so you can't do it this way.

Other solution for what you want to achieve is returning regular (json in my example) response, containing your url you want to perform redirect to, and do it in your success callback by setting window.location.href:

JS:

$.ajax({
    type: "GET",
    url: "http://dev/app_dev.php/device/" + window.id + "/remove",
    dataType: "json",
    error: function(data) {
        console.log("Error in Processing-----" + data.status);
    },
    success: function(urlFromController) {
        window.location.href = urlFromController;
    }
});

Your controller:

use Symfony\Component\HttpFoundation\JsonResponse;
public function removeAction(Request $request, $id = null)
{
    (...)

    $this->get('session')->getFlashBag()->add('message', $flashMessage);
    return new JsonResponse($this->generateUrl('device_list'));
}

Upvotes: 3

joshboley
joshboley

Reputation: 1153

You are probably returning a raw html string to your ajax call. I did some research. I believe you need to this instead:

header("Location:" + $this->generateUrl('device_list')); /* Redirect browser */
exit();

See this answer or this answer for a more detailed description.

$.ajax({
type: "GET",
url: "http://dev/app_dev.php/device/" + window.id + "/remove",
crossDomain: false,
dataType: "html",
complete: function (data) {  // add this option and see what "data" is
    console.log(data);
},
error: function(data) {
    console.log("Error in Processing-----" + data.status);
}

});

Upvotes: 0

Related Questions