how to return json encoded form errors in symfony

前端 未结 6 2016
臣服心动
臣服心动 2020-12-08 03:22

I want to create a webservice to which I submit a form, and in case of errors, returns a JSON encoded list that tells me which field is wrong.

currently I only get a

相关标签:
6条回答
  • 2020-12-08 03:26

    I've finally found the solution to this problem here, it only needed a small fix to comply to latest symfony changes and it worked like a charm:

    The fix consists in replacing line 33

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

    with

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

    because, with the introduction in symfony of Form\Button, a type mismatch will occur in serialize function which is expecting always an instance of Form\Form.

    You can register it as a service:

    services:
    form_serializer:
        class:        Wooshii\SiteBundle\FormErrorsSerializer
    

    and then use it as the author suggest:

    $errors = $this->get('form_serializer')->serializeFormErrors($form, true, true);
    
    0 讨论(0)
  • 2020-12-08 03:26

    This does the trick for me

     $errors = [];
     foreach ($form->getErrors(true, true) as $formError) {
        $errors[] = $formError->getMessage();
     }
    
    0 讨论(0)
  • 2020-12-08 03:42

    This will do the trick. This static method runs recursively through the Symfony\Component\Form\FormErrorIterator delivered by calling $form->getErrors(true, false).

    <?php
    
    
    namespace App\Utils;
    
    
    use Symfony\Component\Form\FormInterface;
    use Symfony\Component\Form\FormError;
    use Symfony\Component\Form\FormErrorIterator;
    
    class FormUtils
    {
        public static function generateErrorsArrayFromForm(FormInterface $form)
        {
            $result = [];
            foreach ($form->getErrors(true, false) as $formError) {
                if ($formError instanceof FormError) {
                    $result[$formError->getOrigin()->getName()] = $formError->getMessage();
                } elseif ($formError instanceof FormErrorIterator) {
                    $result[$formError->getForm()->getName()] = self::generateErrorsArrayFromForm($formError->getForm());
                }
            }
            return $result;
        }
    }
    

    Here is the result :

    {
        "houseworkSection": "All the data of the housework section must be set since the section has been requested.",
        "foodSection": {
            "requested": {
                "requested": "This value is not valid."
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 03:47

    PHP has associative arrays, meanwhile JS has 2 different data structures : object and arrays.

    The JSON you want to obtain is not legal and should be :

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

    So you may want to do something like this to build your collection :

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

    (assuming the getId() method exist on $error objects)

    0 讨论(0)
  • 2020-12-08 03:50

    I am using this, it works quiet well:

    /**
     * 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;
    }
    
    0 讨论(0)
  • 2020-12-08 03:53

    By reading other people's answers I ended up improving it to my needs. I use it in Symfony 3.4.

    To be used in a controller like this:

    $formErrors = FormUtils::getErrorMessages($form);
    
    return new JsonResponse([
        'formErrors' => $formErrors,
    ]);
    

    With this code in a separate Utils class

    <?php
    
    namespace MyBundle\Utils;
    
    use Symfony\Component\Form\FormError;
    use Symfony\Component\Form\FormInterface;
    
    class FormUtils
    {
        /**
         * @param FormInterface $form
         * @return array
         */
        public static function getErrorMessages(FormInterface $form)
        {
            $formName = $form->getName();
            $errors = [];
    
            /** @var FormError $formError */
            foreach ($form->getErrors(true, true) as $formError) {
                $name = '';
                $thisField = $formError->getOrigin()->getName();
                $origin = $formError->getOrigin();
                while ($origin = $origin->getParent()) {
                    if ($formName !== $origin->getName()) {
                        $name = $origin->getName() . '_' . $name;
                    }
                }
                $fieldName = $formName . '_' . $name . $thisField;
                /**
                 * One field can have multiple errors
                 */
                if (!in_array($fieldName, $errors)) {
                    $errors[$fieldName] = [];
                }
                $errors[$fieldName][] = $formError->getMessage();
            }
    
            return $errors;
        }
    }
    
    0 讨论(0)
提交回复
热议问题