ux
ux copied to clipboard
[LiveComponent] Batch request to save function, throws error: The submitForm() method is being called, but the FormView has already been built
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":{}}
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
JSON:
{"props":{
"actions":[
{"name":"save","args":{}},
{"name":"save","args":{}}
]
}
So, whatever leads _batch
to capturing two different events that trigger the same action, is a cause for this, because apparently, the two actions are triggered within the same component's context, thus the underlying form complains in the way reported by @jpvdw86. In his case, the action is save()
, in my case, the action called twice is submit()
. Regardless, the effect is the same - it leads to an exception.
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 _batch
and the error.
#[LiveAction]
public function save(EntityManagerInterface $entityManager): void
{
$this->submitForm();
}
{{ form_widget(form.note, {'attr': {'data-action': 'live#action:prevent', 'data-live-action-param': 'on(change)|save'}}) }}
Error
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?
I have the same problem.
In my case, I have an HTML grid with several forms. In my grid, I can select the fields that I edit. One of the fields is an EntityType, rendered as a select, when it saves, here is the request :
{ "props": { "initialFormData": 13, "company": 13, "company.name": "DUMMY COMPANY", "company.legalName": "DUMMY COMPANY", "editable": true, "columns": [ "id", "name", "address", "registrationNumber", "legalForm" ], "readOnlyColumns": [ "id", "address" ], "personColumns": [ "id", "firstName", "lastName", "phone", "mobile" ], "readOnlyPersonColumns": [ "id" ], "isValid": true, "formName": "company_row", "company_row": { "legalName": "DUMMY COMPANY", "name": "DUMMY COMPANY", "brandName": "", "headQuarter": null, "registrationNumber": "", "registeredAt": "", "vatKey": "", "website": "", "email": "[email protected]", "shareCapital": "", "isEol": null, "phone": "", "activityCode": "", "legalForm": "24", "_token": "3b08b7120c40c35dbd931.1CnyNbe98FLb6mYYA4VCn-n1ZNoQnly0azGgPkfJywI.i227cf_VvRrjxzxVe_B1p7OYAeJG8y7XLgHkeXGf_VaRQbYEg86IIZSLMw" }, "isValidated": true, "validatedFields": [], "@attributes": { "id": "live-1209671343-company_group_39867153_13", "key": "company_group_39867153_13" }, "@checksum": "QS52v1m7uFfOnkJWovQugsnN5IKXkdFWUsJZ5x2AbL4=" }, "updated": { "company_row.legalForm": "57", "validatedFields": [ "company_row.legalForm" ] }, "args": {} }
And it works.
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) :
{ "props": { "initialFormData": 13, "company": 13, "company.name": "DUMMY COMPANY", "company.legalName": "DUMMY COMPANY", "editable": true, "columns": [ "id", "name", "address", "registrationNumber", "legalForm" ], "readOnlyColumns": [ "id", "address" ], "personColumns": [ "id", "firstName", "lastName", "phone", "mobile" ], "readOnlyPersonColumns": [ "id" ], "isValid": true, "formName": "company_row", "company_row": { "legalName": "DUMMY COMPANY", "name": "DUMMY COMPANY", "brandName": "", "headQuarter": null, "registrationNumber": "", "registeredAt": "", "vatKey": "", "website": "", "email": "[email protected]", "shareCapital": "", "isEol": null, "phone": "", "activityCode": "", "legalForm": "57", "_token": "0cd266cd3021abd2a.ENVaEp2ESvr1xw0_rLnsE1-wsE7kB8UQkhNMR1u3PWk.T5ETVtXsB7LN6ldy1MzbKwXd1Xayardz1yMIAG3hCz1VvR4jqfcyibqmWA" }, "isValidated": false, "validatedFields": [], "@attributes": { "id": "live-1209671343-company_group_430929945_13", "key": "company_group_430929945_13" }, "@checksum": "UkbsuEMubWWNvTrlqFFioIQ7OT2+uOhFNZzTX69ZoJQ=" }, "updated": { "company_row.legalForm": "", "validatedFields": [ "company_row.legalForm" ] }, "actions": [ { "name": "save", "args": {} }, { "name": "save", "args": {} } ] }
And it triggers the error
@WebMamba @EOL-Fred
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()). //Symfony\UX\LiveComponent\ComponentWithFormTrait
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();