Embedded Forms won't update even though variableManager is in the correct state

Hi,
I am using an JSON serialised variable of ArrayList and a custom type in as a process variable. I use this technique all over but for some reason it does not seem to be persisting back for this particular use case.
I have set the form loading up as such:

<script cam-script type="text/form-script">
        camForm.on('form-loaded', function() {
            camForm.variableManager.fetchVariable('applicationDocuments');
        });
        
        camForm.on('variables-fetched', function() {
            $scope.applicationDocuments = camForm.variableManager.variable('applicationDocuments').value;
        });

        camForm.on('store', function() {
            camForm.variableManager.variable('applicationDocuments').value = $scope.applicationDocuments;
            console.log(camForm.variableManager.variable('applicationDocuments').value);
        });

        camForm.on('submit', function() {
            camForm.variableManager.variable('applicationDocuments').value = $scope.applicationDocuments;
            console.log(camForm.variableManager.variable('applicationDocuments').value);
        });
  
    </script>

And the form loads the data no problem.
I then use the angular ng-repeat to bind the form.
As you see in the code both console.logs return the CORRECT bound state of the form, so the state management on the client is working.

For some reason this does not then persist to the Engine. It is strange as I have this exact same procedure woking all aver my project.

The only difference is that this time it is an ArrayList<> on the server.

State Before Form Change from:

console.log(camForm.variableManager.variable('applicationDocuments').value);
[Log] Array (6)
0 {documentId: "11", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}
1 {documentId: "6", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}
2 {documentId: "17", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}
3 {documentId: "7", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}
4 {documentId: "8", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}
5 {documentId: "9", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: true, …}

Array Prototype

State AFTER form Change from:

console.log(camForm.variableManager.variable('applicationDocuments').value);
[Log] Array (6)
0 {documentId: "11", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "MARRIAGE_CERTIFICATE_ANTE_NUPTIAL_CONTRACT_OCOP_", includeInApplication: true, …}
1 {documentId: "6", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "PROOF_IF_DIVORCE_DEED_OF_SETTLEMENT", includeInApplication: false, …}
2 {documentId: "17", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: false, …}
3 {documentId: "7", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "COMPLETED_APPLICATION_FORM", includeInApplication: false, …}
4 {documentId: "8", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "PROOF_OF_INCOME", includeInApplication: false, …}
5 {documentId: "9", fileName: "Application Forms.pdf", dateReceived: 1642506609406, documentType: "QUOTATION_OF_VEHICLE", includeInApplication: false, …}

Array Prototype

So camForm.variableManager.variable(‘applicationDocuments’).value is in the correct state but does not persist to the server.

Any ideas?

Just giving this a bump.

Does anyone even know how I would go about debugging this?
Is there a way I can see the variable posts going to the server?

EDIT: More diagnostics has shown me that the form is not being submitted on the ‘store’ event.
However when I “Complete” the task, the form is submitted on the ‘submit’ event.
I double check and this is in fact happening on all my forms. It seems the “save” button is not working form some reason as expected.

EDIT 2: More diagnostics. So it seems that the save button will store the variables to local storage. This can obviously be worked around, however the big issue now is I want to update the variables on the server when I save. I found that I can call “camForm.submit()” in the store event, however this does update the variables, but then also “completes” the task.

Question: How can I save the variables to the server without completing the task?

Hi @SlappyAUS,

long time ago Felix has build an example: code/snippets/task-form-save-to-engine at master · camunda-consulting/code · GitHub

Hope this helps, Ingo

Here is a template if anyone needs this functionality further:
This will override the default behaviour of saving to localStorage and rather persist to server.

<script cam-script type="text/form-script">
        inject(['$http', 'Uri', function ($http, Uri) {
        
            camForm.on('form-loaded', function() {
                camForm.variableManager.fetchVariable('customerApplication');
            });
            
            camForm.on('variables-fetched', function() {
                $scope.customerApplication = camForm.variableManager.variable('customerApplication').value;
            });

            camForm.on('store', function(evt) {
                camForm.variableManager.variable('customerApplication').value = $scope.customerApplication;

                storeVariablesToEngine(evt)
            });

            camForm.on('submit', function() {
                camForm.variableManager.variable('customerApplication').value = $scope.customerApplication;
            });

            function storeVariablesToEngine(evt) {
                evt.retrieveVariables();
        
                var varManager = evt.variableManager;
                var vars = varManager.variables;
        
                var variableData = {};
                for (var v in vars) {
                    if (varManager.isDirty(v)) {
                        var val = vars[v].value;
        
                        if (varManager.isJsonVariable(v)) {
                            val = JSON.stringify(val);
                        }
        
                        variableData[v] = {
                            value: val,
                            type: vars[v].type,
                            valueInfo: vars[v].valueInfo
                        };
                    }
                }
        
                var data = { modifications: variableData };
                var config = {
                    headers: {
                        'Content-Type': 'application/json'
                    }
                };
        
                $http.post(Uri.appUri('engine://engine/:engine/task/' + camForm.taskId + '/variables'), data, config);
        
                evt.storePrevented = true;
            }
        }]);
    </script>