1

i'm newbie in symfony and I'm trying to implement a Data Transformer. I followed the documentation and looked different solutions posted in here. But I haven't found what is wrong with my code.

I'm getting this error:

Catchable Fatal Error: Object of class AppBundle\Entity\Todo could not be converted to string

If someone knows another post with the solution, please tell me know where I could look for it.

Thank you in advance.

So, these are my Entities. Todo class

    <?php

    namespace AppBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;

    /**
     * Todo
     *
     * @ORM\Table(name="todo")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\TodoRepository")
     */  


class Todo
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * @var string
         *
         * @ORM\Column(name="name", type="string", length=20)
         */
        private $name;

        /**
         * @var string
         *
         * @ORM\Column(name="category", type="string", length=20)
         */
        private $category;

        /**
         * @var string
         *
         * @ORM\Column(name="description", type="string", length=10)
         */
        private $description;

        /**
         * @var string
         *
         * @ORM\Column(name="priority", type="string", length=10)
         */
        private $priority;

        /**
         *
         * @ORM\ManyToOne(
         *     targetEntity="AppBundle\Entity\User",
         *     inversedBy="todos"
         * )
         * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
         */
        private $creatorId;

    //... getters and setters

User class:

<?php
// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }

    /**
     * @ORM\OneToMany(
     *     targetEntity="AppBundle\Entity\Todo",
     *     mappedBy="creatorId"
     * )
     */
    private $todos;

}

In the User class, I don't have getter/setters

My TodoType

class TodoType extends AbstractType{

    private $manager;

    public function __construct(ObjectManager $manager)
    {
    $this->manager = $manager;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder

            ->add('name', TextType::class, array(
                'label' => 'Name',
                'required' => true
              )
            )

            ->add('category', TextType::class, array(
                'label' => 'Category'
              )
            )

            ->add('priority', EntityType::class, array(
                'class' => 'AppBundle:Todo',
                'choice_label' => 'priority',
              )
            )

            ->add('creatorId', TextType::class, array(
              'label' => 'creator Id:',
            ));

            $builder->get('creatorId')
                ->addModelTransformer(new IssueToNumberTransformer($this->manager));

    }

    public function getName()
    {
        return 'todo';
    }

}

Transformer

<?php
namespace FOS\UserBundle\Form\DataTransformer;

use AppBundle\Entity\User;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class IssueToNumberTransformer implements DataTransformerInterface
{
    private $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }

    /**
     * Transforms an object (creatorId) to a string (number).
     *
     * @param  creatorId|null $creatorId
     * @return string
     */
    public function transform($creatorId)
    {
        if (null === $creatorId) {
            return '';
        }

        return $creatorId->getId();

    }

    /**
     * Transforms a string (number) to an object (creatorId).
     *
     * @param  string $creatorId
     * @return creatorId|null
     * @throws TransformationFailedException if object (creatorId) is not found.
     */
    public function reverseTransform($creatorId)
    {
        // no issue number? It's optional, so that's ok
        if (!$creatorId) {
            return;
        }

        $creatorId = $this->manager
            ->getRepository('AppBundle:User')
            // query for the issue with this id
            ->find($creatorId);


        if (null === $creatorId) {
            throw new TransformationFailedException(sprintf(
                'A user with number "%s" does not exist!',
                $creatorId
            ));
        }

        return $creatorId;
    }
}

Controller (function)

  public function createAction(Request $request){

        $em = $this->getDoctrine()->getManager();

        // 1) build the form
        $todo = new Todo();

        $form = $this->createForm(new TodoType($em), $todo);

        // 2) handle the submit (will only happen on POST)
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

          // 3) save the Todo!
          $em->persist($todo);
          $em->flush();

        return $this->redirectToRoute('todo_create');

      }

        return $this->render('todo/create.html.twig', array(
            'todo'=>$todo,
            'form'=>$form->createView()
        ));

    }

1 Answer 1

2

It's at this part:

return $this->render('todo/create.html.twig', array(
      'todo'=>$todo,
      'form'=>$form->createView()
));

Because you are trying to pass the $todo object to your Twig template. You can't do that. What do you need? If you just need the Todo name and you have created getters/setter, you could instead do like this:

return $this->render('todo/create.html.twig', array(
      'todo_name' => $todo->getName(),
      'form' => $form->createView()
));

Hopefully that makes sense.


EDIT #2 based on comments.

Also this line is wrong in your controller:

$form = $this->createForm(new TodoType($em), $todo);

Should be like this:

$form = $this->createForm(TodoType::class, $todo);
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you @AlvinBunk, it make sense I dont need to render the "todo". I removed that line. But I'm still getting the same error :I
Can you use the debug URL by appending app_dev.php after your hostname. Like http://localhost/app_dev.php/my_route and see if that shows more info? I'm looking for which file and which line the error is occurring on.
I also added an EDIT #2.
I opened this URL localhost:8000/app_dev.php/todo/create the form is displayed. I don't see anything strange. Is that page what you meant?
EDIT # 2 I also tried before, and nothing. Same issue
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.