Estoy tratando de registrar un usuario con AJAX.
Creé un detector de eventos en FOSUserEvents::REGISTRATION_SUCCESS
Entonces, estoy tratando de saber si se realizó una solicitud AJAX pero la respuesta en mi lado del cliente no me satisface.
Aquí, mi oyente de eventos, tenga en cuenta que la respuesta enviada es una prueba, por lo que, por supuesto, no debería haber ninguna condición "otra cosa".
<?php namespace SE\AppBundle\EventListener; use FOS\UserBundle\FOSUserEvents; use FOS\UserBundle\Event\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RequestStack; /** * Ajax listener on FOS UserBundle registration */ class RegistrationListener implements EventSubscriberInterface { private $router; public function __construct(RequestStack $RequestStack) { $this->requestStack = $RequestStack; } /** * {@inheritDoc} */ public static function getSubscribedEvents() { return array( FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess' ); } public function onRegistrationSuccess() { $request = $this->requestStack->getCurrentRequest(); if ($request->isXmlHttpRequest()) { $array = array( 'success' => true ); // data to return via JSON $response = new Response( json_encode( $array ) ); $response->headers->set( 'Content-Type', 'application/json' ); return $response; } else{ $array = array( 'success' => false ); // data to return via JSON $response = new Response( json_encode( $array ) ); $response->headers->set( 'Content-Type', 'application/json' ); return $response; } } }
services.yml
:
se.app.listener.registration: class: SE\AppBundle\EventListener\RegistrationListener arguments: ["@request_stack"] tags: - { name: kernel.event_subscriber }
JavaScript:
// Submit the request $.ajax({ type : 'POST', url : url, data : data, success : function(data, status, object) { console.log('success'); console.log(data); }, error: function(data, status, object){ console.log('error'); console.log(data); } });
En primer lugar, lo extraño es que va en la condición de error.
console.log
(datos) se devuelve el DOM de la página de éxito del registro:
... <p>Congrats brieuc.tribouillet7777@gmail.com, your account is now activated.</p> ...
Entonces, ¿esta lógica debería estar aquí o debería anular el controlador? ¿Qué estoy haciendo mal?
Debido al nivel del evento REGISTRATION_SUCCESS
, no puede devolver una respuesta directamente desde EventListener
.
Debe tomar el FormEvent
y modificar su respuesta.
Pasemoslo como argumento:
class RegistrationListener implements EventSubscriberInterface { // ... public function onRegistrationSuccess(FormEvent $event) { $request = $this->requestStack->getCurrentRequest(); // Prepare your response if ($request->isXmlHttpRequest()) { $array = array( 'success' => true ); // data to return via JSON $response = new Response( json_encode( $array ) ); $response->headers->set( 'Content-Type', 'application/json' ); } else { $array = array( 'success' => false ); // data to return via JSON $response = new Response( json_encode( $array ) ); $response->headers->set( 'Content-Type', 'application/json' ); } // Send it $event->setResponse($response); } }
Y debería funcionar.
Nota Hay un problema con este evento en el que la respuesta no se puede modificar.
Si ocurre el problema, debe establecer una prioridad baja en la suscripción de su evento:
public static function getSubscribedEvents() { return [ FOSUserEvents::REGISTRATION_SUCCESS => [ ['onRegistrationSuccess', -10], ], ]; }
Ver #1799 .
EDITAR
Nota Debe usar JsonResponse en lugar de json_encode
sus datos y configurar el Content-Type
manualmente.
Para capturar el formulario en sí y sus eventuales errores, puede hacer esto:
public function onRegistrationSuccess(FormEvent $event) { $form = $event->getForm(); if (count($validationErrors = $form->getErrors()) == 0) { return $event->setResponse(new JsonResponse(['success' => true])); } // There is some errors, prepare a failure response $body = []; // Add the errors in your response body foreach ($validationErrors as $error) { $body[] = [ 'property' => $error->getPropertyPath() // The field 'message' => $error->getMessage() // The error message ]; } // Set the status to Bad Request in order to grab it in front (ie $.ajax({ ...}).error(...)) $response = new JsonResponse($body, 400); $event->setResponse($response); }
Pero debido a que es un evento exitoso, es posible que deba anular el método en sí.