hous
hous

Reputation: 2679

How to browse the form errors

I'd like to browse the form errors but I it doesn't work for me.

I tried it without ajax and I this is the error

An exception has been thrown during the rendering of a template ("Notice: Array to string conversion") 
in AppBundle:Admin:errors-form.html.twig at line 5.

I think that the problem is how to loop this line using twig:

    'data' => $this->getErrorMessages($form),

This is the code

protected function getErrorMessages(\Symfony\Component\Form\Form $form)
{
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        $errors[] = $error->getMessage();
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = $this->getErrorMessages($child);
        }
    }

    return $errors;
}


public function addAction(Request $request)
{
    if ($form->isValid()) {
        //..
    } else {

        $view = $this->renderView(
            'AppBundle:Admin:errors-form.html.twig', array(
                'data' => $this->getErrorMessages($form),
            )
        );
        $response = new JsonResponse(array(
                'view' => $view,
                'result' => 0,
                'message' => 'Invalid form',
            )
        );
        return $response;

    }


}

This is the view returned with JsonResponse in case of errors , but the errors are not displayed, but if I put a static text in this view it will appear after submit

<div id="error">

    {% for error in data %}

        {{ error }}

    {% endfor %}
</div>

Upvotes: 0

Views: 299

Answers (3)

rouflak
rouflak

Reputation: 154

The getErrors method only returns the first level of the form which means the form itself and not its children.

You need to provide the boolean argument to have the method search deep in the form: getErrors(true)

protected function getErrorMessages(\Symfony\Component\Form\Form $form)
{
    // ...

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

    // ...

    return $errors;
}

See symfony documentation http://symfony.com/doc/current/components/form/introduction.html#accessing-form-errors

EDIT

I didn't pay attention to the beginning. The error in you template is due to the following piece of code:

foreach ($form->all() as $child) {
    if (!$child->isValid()) {
        $errors[$child->getName()] = $this->getErrorMessages($child);
    }
}

$this->getErrorMessages($child) is actually returning an array, not a string. You need to do as follows:

foreach ($form->all() as $child) {
    if (!$child->isValid()) {
        foreach ($this->getErrorMessages($child) as $error) {
            $errors[$child->getName()] .= ' '.$error
        }

    }
}

Upvotes: 0

hous
hous

Reputation: 2679

It must be two {% for %} loop , and I have fixed it like this and now it works good.

<div id="error">

    {% for data in data %}
        {% for error in data %}
            {{ error }}<br>
        {% endfor %}

    {% endfor %}

</div>

Upvotes: 0

LdiCO
LdiCO

Reputation: 577

if you want just get the errors and show them in the twig, No need for the getErrorMessages. You could pass the form $form to the view:

public function addAction(Request $request)
{
    if ($form->isValid()) {
    //..
} else {
    $view = $this->renderView(
        'AppBundle:Admin:erreurs-form.html.twig', array(
            'form' => $form,
        )
    );
    $response = new JsonResponse(array(
            'view' => $view,
            'result' => 0,
            'message' => 'Invalid form',
        )
    );
    return $response;
  }
}

and use the built-in form_errors in the twig to fetch errors and show them:

{% if form_errors(form) %}
<div id="error">
    {{ form_errors(form) }}
</div>
{% endif %}

Or could get the errors in the Controller by :

$view = $this->renderView(
        'AppBundle:Admin:erreurs-form.html.twig', array(
            'data' => $form->getErrors()
        )
    );

and use this to handle it in the twig :

<div id="error">
{% for error in data %}
    {{ error.message }}        
{% endfor %}
</div>

Upvotes: 2

Related Questions