Erich
Erich

Reputation: 545

error when rendering Symfony 4 edit form that includes a File type

I'm following the steps outlined in this documentation https://symfony.com/doc/current/controller/upload_file.html to allow a file to be uploaded. It is working perfectly for adding a new item, but when I try to edit my entity, I'm getting the following error:

The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.

I've tried code like what is suggested in that article to append the path of the folder as File type to the entity like this in my update method:

public function editAction(Request $request, Advertiser $advertiser)
{

    $advertiser->setLogo(
        new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
    );

    $editForm = $this->createForm(AdvertiserType::class, $advertiser);

    $editForm->handleRequest($request);
    if ($editForm->isSubmitted() && $editForm->isValid()) {
        $this->getDoctrine()->getManager()->flush();
        return $this->redirectToRoute('advertiser_list');
    }
    return $this->render('advertiser/index.html.twig', [
        'form' => $editForm->createView()
    ]);
}

The logo_directory parameter is properly defined (and working fine for creating new entities).

Please let me know if you have any ideas what I am doing wrong.

Thanks for the help.

UPDATE: In this article The form's view data is expected to be an instance of class ... but is a(n) string there is a proposed solution to include in the form builder code the following:

->add('file', FileType::class, array('data_class' => null))

So I'm doing this now and the edit form will show - but it doesn't prepoulate with the previous selection.

->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])

Any thoughts on how this can be changed to allow the form to show with the previous selection pre-populated?

Upvotes: 2

Views: 2067

Answers (1)

tchap
tchap

Reputation: 3432

Setting a null data_class will remove the warning but it will not work, you don't need it at this point.

This is due to the fact that once your file is persisted, what remains in your database is just a path, not the file itself (which is on disk);

If you want to edit this entity again, the path (a string) must be converted to a File entity again; That's what the error message says.

.. and this is what you did when you wrote :

$advertiser->setLogo(
    new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);

Now, the problem that remains is that you want to prepopulate the file field. In fact, that is not possible, since the file field points to a location in your own computer, not to a file on your server (and you cannot automatically upload something from someone's computer like that, that would be very dangerous).

What you want to do is possibly indicate that a file is already stored, get its path and maybe display it to your user.

So in your Twig template, something like that (change with your real logo directory) :

{% if form.logo.vars.data %}
  <img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}

Hope it's clear.

Upvotes: 3

Related Questions