craue / CraueFormFlowBundle

Multi-step forms for your Symfony project.
MIT License
736 stars 118 forks source link

Flow expires with Ajax (Symonfy 3.4) #317

Closed WimWidgets closed 6 years ago

WimWidgets commented 6 years ago

I'm working on a mobile app with a Symfony backend. The app contains some forms for login, registration and so on. Since Symfony has a great form system with built-in validation and entity mapping, I wanted to use these forms in my app via Ajax, where the app just displays the form and possible errors. This works great and I even had the form flow up in running within a previous Symfony 3.3 project. I am now working on an app using the exact same setup, but this time I'm using Symfony 3.4. Now all of sudden I get an expired error everytime I post the first form of a flow. Below is a simplified testcase with just the basics.

Situation 1: regular controller route with a form in twig template posting to itself.

<?php

namespace MyBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class MyController extends Controller
{
    /**
     * @Route("")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function myAction(Request $request)
    {
        $myEntity = new MyEntity();

        // A
        $flow = $this->get('my.flow.service');
        dump(
            $request->request->get($flow->getInstanceKey()),
            $flow->getInstanceId()
        );

        // B
        $flow->bind($myEntity);
        dump(
            $request->request->get($flow->getInstanceKey()),
            $flow->getInstanceId()
        );

        $form = $flow->createForm();
        if ($flow->isValid($form)) {
            $flow->saveCurrentStepData($form);
            if ($flow->nextStep()) {
                $form = $flow->createForm();
            } else {
                $flow->reset();
            }
        }

        return $this->render('view.html.twig', [
            'form' => $form->createView()
        ]);
    }    
}

Dump results:

State Dump Output
Initial load A null, "my_flow"
Initial load B null, "2zbQrUVVor"
Post step 1 A "2zbQrUVVor", "my_flow"
Post step 1 B "2zbQrUVVor", "2zbQrUVVor"

Situation 2: a rest controller posted to by Ajax

<?php

namespace MyApiBundle\Controller;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;

class MyController extends FOSRestController
{
    /**
     * @Rest\Post("")
     * @param Request $request
     * @return \FOS\RestBundle\View\View
     */
    public function myAction(Request $request)
    {
        $myEntity = new MyEntity();

        // A
        $flow = $this->get('my.flow.service');
        dump(
            $request->request->get($flow->getInstanceKey()),
            $flow->getInstanceId()
        );

        // B
        $flow->bind($myEntity);
        dump(
            $request->request->get($flow->getInstanceKey()),
            $flow->getInstanceId()
        );

        $form = $flow->createForm();
        if ($flow->isValid($form)) {
            $flow->saveCurrentStepData($form);
            if ($flow->nextStep()) {
                $form = $flow->createForm();
            } else {
                $flow->reset();
            }
        }

        return $this->view([
            'form' => $form->createView(),
            'step' => $flow->getCurrentStepNumber()
        ]);
    }
}

Dump results:

State Dump Output
Initial load A null, "my_flow"
Initial load B null, "4rlOCw-Bpu"
Post step 1 A "4rlOCw-Bpu", "my_flow"
Post step 1 B null, "-fCcnw2PIw"

Even though the flow instance ID is posted back correctly by the Ajax call, the flow somehow creates a new instance ID and everything starts from scratch again. I could switch back to Symfony 3.3 where it worked, but I'd rather use 3.4 because it's an LTS version. So this isn't really a bug report, but does anyone here maybe have idea what causes the issue and possibly have a fix?

WimWidgets commented 6 years ago

Never mind. In the end it was just a little Javascript thing.