Liform icon indicating copy to clipboard operation
Liform copied to clipboard

Undefined array key "compound" on liform->transform($form)

Open OliverOlesen opened this issue 1 year ago • 6 comments

Been trying for the longest time to solve this without any luck, so I'm writing this here as a last stand.

The following is one of the first controllers I've made, which is where i would be using Liform

class CreateController extends AbstractController
{

    public function __construct(private readonly CategoryProjector $categoryProjector, private readonly Liform $liform)
    {
    }

    #[Route('/api/management/categories/create', name: 'management.categories.create', methods:['get', 'post'])]
    public function __invoke(Request $request, EntityManagerInterface $entityManager): Response
    {
        $categoryModel = new CategoryModel();

        $form = $this->createForm(CategoryCreateType::class, $categoryModel, );

       if ($form->isSubmitted() && $form->isValid()) {
           $event = new CategoryCreated($categoryModel);
           $this->categoryProjector->ApplyCategoryCreated($event);
           return new Response(Response::HTTP_OK);
       }

        if ($request->isMethod('GET')) {
            return new Response(json_encode($this->liform->transform($form)));
        }

        return new Response(Response::HTTP_BAD_REQUEST);
    }
}

But no matter what i try, it always comes back to the same error Undefined array key "compound" when i use $liform->transform.

I then went to the line where the issue happened and for some reason the types are not what I at least expected them to be. So just for context, this is the function in resolver where it breaks. specifically here 'transformer' => $this->transformers['compound']['transformer'], which when looking at what it receives makes sense, if it's supposed to be an array of the different types anyway.

public function resolve(FormInterface $form)
    {
        $types = FormUtil::typeAncestry($form);

        foreach ($types as $type) {
            if (isset($this->transformers[$type])) {
                return $this->transformers[$type];
            }
        }

        // Perhaps a compound we don't have a specific transformer for
        if (FormUtil::isCompound($form)) {
            return [
                'transformer' => $this->transformers['compound']['transformer'],
                'widget' => null,
            ];
        }

        throw new TransformerException(
            sprintf(
                'Could not find a transformer for any of these types (%s)',
                implode(', ', $types)
            )
        );
    }

for further context, this is the Form which i am trying to transform.

class CategoryCreateType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
            $builder
                ->add('type', TextType::class, [
                    'required' => false,
                    'attr' => [
                        'placeholder' => 'Category Type',
                    ]
                ]);
            $builder
                ->add('name', TextType::class, [
                    'required' => true,
                ]);
            $builder
                ->add('description', TextType::class, [
                    'required' => false,
                ]);
            $builder
                ->add('image', FileType::class, [
                    'required' => true,
                ]);
    }
}

But for some reason in Resolver.php, the $types array gets the following, instead of the actual types in the form. [0]: 'category_create', [1]: 'form' image

If i am lucky enough to have anyone read this that might have an idea as to what could be the issue, please let me know, i am utterly lost.

OliverOlesen avatar Jul 07 '24 15:07 OliverOlesen

I forget when the ?? (null coalese) operator was introduced, but a simple fix would be

 $this->transformers['compound']['transformer']??null

tacman avatar Jul 07 '24 15:07 tacman

I've tracked this down to the transformers not being loaded during the compiler pass. I haven't solved it, and when I try to replicate the problem is a small and concise test it, it works. I hope to find it though, it's maddening.

I'll also update the documentation at that time.

tacman avatar Dec 03 '24 10:12 tacman

I encounter also this same problem (after updating Symfony) that the transformers are not loaded duging the compiler pass. Any solutions yet ?

ewoutj avatar Jan 14 '25 10:01 ewoutj

I went down a refactoring path that fixed that (injecting the transformers during the compiler pass), but broke something else in the process. I'm traveling now, but when I get back I'll post what I did and where I'm stuck.

On Tue, Jan 14, 2025 at 5:34 AM ewoutj @.***> wrote:

I encounter also this same problem (after updating Symfony) that the transformers are not loaded duging the compiler pass. Any solutions yet ?

— Reply to this email directly, view it on GitHub https://github.com/Limenius/Liform/issues/74#issuecomment-2589559996, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEXIQKIR3C34TRPABOEEMT2KTR2XAVCNFSM6AAAAABKPN5AFGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOBZGU2TSOJZGY . You are receiving this because you commented.Message ID: @.***>

tacman avatar Jan 14 '25 12:01 tacman

Just a heads up, i resolved it by using attributes. E.g: #[AutoconfigureTag(name:'liform.transformer', attributes: ['form_type' => 'compound'])] class CompoundTransformer extends AbstractTransformer

ewoutj avatar Jan 15 '25 11:01 ewoutj

Very cool, I forgot about that! Can you submit a PR?

tacman avatar Jan 15 '25 13:01 tacman