-
-
Notifications
You must be signed in to change notification settings - Fork 356
[LiveComponent] Batch request to save function, throws error: The submitForm() method is being called, but the FormView has already been built #1509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey @jpvdw86 are you up to sharing a little reproducer? It can be easier to help you! 😁 |
Hi @WebMamba, The same thing is happening to me, too. While I can not help by sharing a reproducer, as @jpvdw86 said, I also have some anecdotal evidence that says this happens while user is doing multiple unrelated actions in the form quickly enough for JS to decide to batch multiple operations together. The issue is triggered by the following part of the {"props":{
"actions":[
{"name":"save","args":{}},
{"name":"save","args":{}}
]
} So, whatever leads Hopefully this gives you some clues as to where the issue might lie? |
I'm running into the same issue. Have also tried debounce but doing things fast enough leads to
Error
|
I have the same problem. When I set the option autocomplete to true (with UX Autocomplete), when I save it triggers a _batch request (no need to edit multiple fields at the same time) : |
This issue is caused by the following code: //Symfony\UX\LiveComponent\Controller\BatchController.php foreach ($actions as $action) {
$name = $action['name'] ?? throw new BadRequestHttpException('Invalid JSON');
$subRequest = $request->duplicate(attributes: [
'_controller' => [$serviceId, $name],
'_component_action_args' => $action['args'] ?? [],
'_mounted_component' => $_mounted_component,
'_live_component' => $serviceId,
]);
$response = $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
if ($response->isRedirection()) {
return $response;
}
} In this scenario, the function is invoked within the same HTTP request (kernel instance). As a consequence of the first request, formValues has become non-nullable. Subsequently, the second request checks for this and triggers the error. The Symfony\UX\LiveComponent\ComponentWithFormTrait does not support batch request behavior by default. I've already attempted to use $this->resetForm() function. However, this did not resolve the error. The resetForm function reinitializes this->formView (using $this->getFormView()). private function resetForm(): void
{
// prevent the system from trying to submit this reset form
$this->shouldAutoSubmitForm = false;
$this->form = null;
$this->formView = null;
$this->formValues = $this->extractFormValues($this->getFormView());
} I haven't investigated further, and perhaps the fix is simple by adjusting the order in the resetForm function to the following: private function resetForm(): void
{
// prevent the system from trying to submit this reset form
$this->formValues = $this->extractFormValues($this->getFormView());
$this->shouldAutoSubmitForm = false;
$this->form = null;
$this->formView = null;
} @weaverryan, perhaps you can provide a simple answer to this. If it's that straightforward, I'll submit a pull request for it. For now, I'm using the following code to fix this issue: if (null !== $this->formView) {
$this->shouldAutoSubmitForm = false;
$this->form = null;
$this->formView = null;
}
$this->submitForm(); |
@WebMamba when will this be resolved? |
I just tried something derived from your suggestion @jpvdw86 (thank you very much) /**
* Reset the form to its initial state, so it can be used again.
*/
- private function resetForm(): void
+ private function resetForm(?bool $soft = false): void
{
// prevent the system from trying to submit this reset form
$this->shouldAutoSubmitForm = false;
$this->form = null;
$this->formView = null;
+ if (true !== $soft) {
$this->formValues = $this->extractFormValues($this->getFormView());
+ }
}
private function submitForm(bool $validateAll = true): void
{
if (null !== $this->formView) {
+ $this->resetForm(true);
- throw new \LogicException('The submitForm() method is being called, but the FormView has already been built. Are you calling $this->getForm() - which creates the FormView - before submitting the form?');
}
$form = $this->getForm();
$form->submit($this->formValues); What we lose
What we keep
What we win
What do you all think? Seems OK ? Could some of you maybe just test if this does fix your problems ? |
I've opened the PR, if you guys can check it that'd be nice! |
…atch actions (smnandre) This PR was merged into the 2.x branch. Discussion ---------- [LiveComponent] Fix ComponentWithFormTrait not working in batch actions | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Issues | Fix #1509 | License | MIT Fix #1509 Thank you `@jpvdw86` for your work on this! 👏 Some parts of your PR would have introduced changes affecting all LiveComponent instances, including those not using ComponentWithFormTrait. To keep the impact as minimal as possible, I’ve opted for a more targeted fix. But _you_ did all the hard work here—much appreciated! 🚀 Commits ------- 466c4eb [LiveComponent] Fix ComponentWithFormTrait not working in batch actions
A normal request works fine, however, if you edit multiple fields at the same time, the event is converted into a _batch request. When this happens, I get the following error 99% of the time: The submitForm() method is being called, but the FormView has already been built.
Example batch request body
{"props":{"inputModel":{"date_filter":{"min_date":"2024-02-16T00:00:00+01:00","max_date":null},"import":false,"invoice":{"line_items":[],"children":true,"groups":[{"line_items":[],"group_code":null,"description":"","children":true,"groups":[{"line_items":[{"vatable":true,"description":"Voertuig","financial_party":null,"amount_ex_vat":1200,"vat_amount":252,"totals":{"amountExVat":1200,"vatAmount":252,"amountInclVat":1452,"vatRate":21},"calculated_vat_rate":21},{"vatable":true,"description":"Rest BPM","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0}],"group_code":"purchase","description":"Inkoop","children":false,"groups":[],"totals":{"totalAmountExVat":1200,"totalVatableAmountExVat":1200,"totalVatAmount":252,"totalAmountInclVat":1452,"groupedVat":{"21":{"vatAmount":252,"amountExVat":1200}}}},{"line_items":[{"vatable":true,"description":"Transportkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0}],"group_code":"costs","description":"Kosten","children":false,"groups":[],"totals":{"totalAmountExVat":0,"totalVatableAmountExVat":0,"totalVatAmount":0,"totalAmountInclVat":0,"groupedVat":[]}},{"line_items":[{"vatable":true,"description":"Optische herstelkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0},{"vatable":true,"description":"Technische herstelkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0},{"vatable":true,"description":"Reconditionering fee","financial_party":null,"amount_ex_vat":302,"vat_amount":63.42,"totals":{"amountExVat":302,"vatAmount":63.42,"amountInclVat":365.42,"vatRate":21},"calculated_vat_rate":21}],"group_code":"expected_costs","description":"Verwachte kosten","children":false,"groups":[],"totals":{"totalAmountExVat":302,"totalVatableAmountExVat":302,"totalVatAmount":63.42,"totalAmountInclVat":365.42,"groupedVat":{"21":{"vatAmount":63.42,"amountExVat":302}}}}],"totals":{"totalAmountExVat":1502,"totalVatableAmountExVat":1502,"totalVatAmount":315.42,"totalAmountInclVat":1817.42,"groupedVat":{"21":{"vatAmount":315.42,"amountExVat":1502}}}}],"totals":{"totalAmountExVat":1502,"totalVatableAmountExVat":1502,"totalVatAmount":315.42,"totalAmountInclVat":1817.42,"groupedVat":{"21":{"vatAmount":315.42,"amountExVat":1502}}}},"top_down_protocol":"App\\Domain\\Inflow\\Settings\\Resolver\\Model\\TopDownPurchaseProtocol"},"vehicle":255,"source":"Aanmaken dossier","personalValuationModel":{"value":4353,"etr":2,"valuationId":4232},"readOnly":false,"protocol":"topdown_purchase","formName":"valuation_form","valuation_form":{"value":"4.353","etr":"2","delete":null,"_token":"90c999283.CNUvXgcEh9QobFpu-5FLj-RGoLObCobHhB_3m1OhB9E.P6J3D2Qpz5VFFQJbjtA5_bUfycmvZ7W-wXuzwz6UT45q5EBpVE7kkUscNQ"},"isValidated":true,"validatedFields":[],"@attributes":{"data-live-id":"live-614878759-0"},"@checksum":"zePMOuTPbTkvAMsm//7BfefQOs1i2hHzBzfWqCus2ro="},"updated":{"valuation_form.etr":"2","validatedFields":["valuation_form.etr"]},"actions":[{"name":"save","args":{}},{"name":"save","args":{}}]}
Normal save action, that works fine:
{"props":{"inputModel":{"date_filter":{"min_date":"2024-02-16T00:00:00+01:00","max_date":null},"import":false,"invoice":{"line_items":[],"children":true,"groups":[{"line_items":[],"group_code":null,"description":"","children":true,"groups":[{"line_items":[{"vatable":true,"description":"Voertuig","financial_party":null,"amount_ex_vat":1200,"vat_amount":252,"totals":{"amountExVat":1200,"vatAmount":252,"amountInclVat":1452,"vatRate":21},"calculated_vat_rate":21},{"vatable":true,"description":"Rest BPM","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0}],"group_code":"purchase","description":"Inkoop","children":false,"groups":[],"totals":{"totalAmountExVat":1200,"totalVatableAmountExVat":1200,"totalVatAmount":252,"totalAmountInclVat":1452,"groupedVat":{"21":{"vatAmount":252,"amountExVat":1200}}}},{"line_items":[{"vatable":true,"description":"Transportkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0}],"group_code":"costs","description":"Kosten","children":false,"groups":[],"totals":{"totalAmountExVat":0,"totalVatableAmountExVat":0,"totalVatAmount":0,"totalAmountInclVat":0,"groupedVat":[]}},{"line_items":[{"vatable":true,"description":"Optische herstelkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0},{"vatable":true,"description":"Technische herstelkosten","financial_party":null,"amount_ex_vat":0,"vat_amount":0,"totals":{"amountExVat":0,"vatAmount":0,"amountInclVat":0,"vatRate":0},"calculated_vat_rate":0},{"vatable":true,"description":"Reconditionering fee","financial_party":null,"amount_ex_vat":302,"vat_amount":63.42,"totals":{"amountExVat":302,"vatAmount":63.42,"amountInclVat":365.42,"vatRate":21},"calculated_vat_rate":21}],"group_code":"expected_costs","description":"Verwachte kosten","children":false,"groups":[],"totals":{"totalAmountExVat":302,"totalVatableAmountExVat":302,"totalVatAmount":63.42,"totalAmountInclVat":365.42,"groupedVat":{"21":{"vatAmount":63.42,"amountExVat":302}}}}],"totals":{"totalAmountExVat":1502,"totalVatableAmountExVat":1502,"totalVatAmount":315.42,"totalAmountInclVat":1817.42,"groupedVat":{"21":{"vatAmount":315.42,"amountExVat":1502}}}}],"totals":{"totalAmountExVat":1502,"totalVatableAmountExVat":1502,"totalVatAmount":315.42,"totalAmountInclVat":1817.42,"groupedVat":{"21":{"vatAmount":315.42,"amountExVat":1502}}}},"top_down_protocol":"App\\Domain\\Inflow\\Settings\\Resolver\\Model\\TopDownPurchaseProtocol"},"vehicle":255,"source":"Aanmaken dossier","personalValuationModel":{"value":4353,"etr":4,"valuationId":4232},"readOnly":false,"protocol":"topdown_purchase","formName":"valuation_form","valuation_form":{"value":"4.353","etr":"4","delete":null,"_token":"a83e3401b4758c18f7529d5d5f4cc.3E69vLJqTsTTkD2XPa0QP6oOMOtFtpaeCeEujEJI_Jg.6znl7dFHBoW-6WWiSOxiTftXWZFx26XnTIVq1C99tMe-f9KL4SAtgbDgUg"},"isValidated":true,"validatedFields":[],"@attributes":{"data-live-id":"live-614878759-0"},"@checksum":"bHPdAhbWdZPi+A/x05NDs1CHCD7w0m29PAbJBVgQfH0="},"updated":{"valuation_form.etr":"2","validatedFields":["valuation_form.etr"]},"args":{}}
The text was updated successfully, but these errors were encountered: