when the serializing serialize has detected create been php ajax json forms symfony

php - the - cómo devolver los errores de forma codificada en json en Symfony



symfony serializer (4)

Quiero crear un servicio web al que presento un formulario y, en caso de errores, devuelve una lista codificada en jason que me indica qué campo es incorrecto.

actualmente solo recibo una lista de mensajes de error pero no un ID de HTML o un nombre de los campos con errores

aquí está mi código actual

public function saveAction(Request $request) { $em = $this->getDoctrine()->getManager(); $form = $this->createForm(new TaskType(), new Task()); $form->handleRequest($request); $task = $form->getData(); if ($form->isValid()) { $em->persist($task); $em->flush(); $array = array( ''status'' => 201, ''msg'' => ''Task Created''); } else { $errors = $form->getErrors(true, true); $errorCollection = array(); foreach($errors as $error){ $errorCollection[] = $error->getMessage(); } $array = array( ''status'' => 400, ''errorMsg'' => ''Bad Request'', ''errorReport'' => $errorCollection); // data to return via JSON } $response = new Response( json_encode( $array ) ); $response->headers->set( ''Content-Type'', ''application/json'' ); return $response; }

esto me dará una respuesta como

{ "status":400, "errorMsg":"Bad Request", "errorReport":{ "Task cannot be blank", "Task date needs to be within the month" } }

pero lo que realmente quiero es algo como

{ "status":400, "errorMsg":"Bad Request", "errorReport":{ "taskfield" : "Task cannot be blank", "taskdatefield" : "Task date needs to be within the month" } }

¿Cómo puedo lograr eso?


Esto hace el truco para mi

$errors = []; foreach ($form->getErrors(true, true) as $formError) { $errors[] = $formError->getMessage(); }


Estoy usando esto, funciona bastante bien:

/** * List all errors of a given bound form. * * @param Form $form * * @return array */ protected function getFormErrors(Form $form) { $errors = array(); // Global foreach ($form->getErrors() as $error) { $errors[$form->getName()][] = $error->getMessage(); } // Fields foreach ($form as $child /** @var Form $child */) { if (!$child->isValid()) { foreach ($child->getErrors() as $error) { $errors[$child->getName()][] = $error->getMessage(); } } } return $errors; }


Finalmente encontré la solución a este problema here , solo necesitaba una pequeña solución para cumplir con los últimos cambios de Symfony y funcionó a la perfección:

El arreglo consiste en reemplazar la línea 33.

if (count($child->getIterator()) > 0) {

con

if (count($child->getIterator()) > 0 && ($child instanceof /Symfony/Component/Form/Form)) {

porque, con la introducción en Symfony de Form / Button, se producirá una falta de coincidencia de tipos en la función de serialización que espera siempre una instancia de Form / Form.

Puedes registrarlo como un servicio:

services: form_serializer: class: Wooshii/SiteBundle/FormErrorsSerializer

y luego usarlo como el autor sugiere:

$errors = $this->get(''form_serializer'')->serializeFormErrors($form, true, true);


PHP tiene matrices asociativas, mientras que JS tiene 2 estructuras de datos diferentes: objeto y matrices.

El JSON que desea obtener no es legal y debería ser:

{ "status":400, "errorMsg":"Bad Request", "errorReport": { "taskfield" : "Task cannot be blank", "taskdatefield" : "Task date needs to be within the month" } }

Así que quizás quieras hacer algo como esto para construir tu colección:

$errorCollection = array(); foreach($errors as $error){ $errorCollection[$error->getId()] = $error->getMessage(); }

(asumiendo que el método getId () existe en $ objetos de error)