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)