[SalesForce] save two records in two objects with a single save button with lightning components

I have two objects: question and answer, in one form.
the first 3 fields belong to the question object.
dynamic form belongs to the response object.

I created two actions in the client-side controller that invoked two other actions in the server-side controller.
when I click on the button save, I receive the alert as if everything went well but nothing really save.

below the screenshot:

[![enter image description here][1]][1]

and code in client-side controller.

  Save: function(component, event, helper) {

if (helper.validateRequiredQuestion(component, event)) { var action1 = component.get("c.saveQuestions"); action1.setParams({ "Quest": component.get("v.QuestionLi") }); // set call back action1.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS" ) { component.set("v.QuestionLi", []); helper.createObjectDataa(component, event); alert('question saved'); } }); // enqueue the server side action
$A.enqueueAction(action1); } if (helper.validateRequired(component, event)) { var action = component.get("c.saveReponses"); action.setParams({ "ListReponse": component.get("v.ReponseList") }); // set call back action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS" ) { component.set("v.ReponseList", []); helper.createObjectData(component, event); alert('reponse saved'); } }); // enqueue the server side action
$A.enqueueAction(action); }

},

Server-side controller

public with sharing class SurveyItelios_addDeleteController {
   @AuraEnabled  
    public static void saveReponses(List ListReponse){
        Insert ListReponse;
    }
   @AuraEnabled  
    public static void saveQuestions(List Quest){
        Insert Quest;
    }
}

here is the code component

<aura:handler name="DeleteRowEvt" event="c:SurveyItelios_DeleteRowEvt" action="{!c.removeDeletedRow}"/>
<aura:handler name="AddRowEvt" event="c:SurveyItelios_AddNewRowEvt" action="{!c.addNewRow}"/>

<aura:attribute name="ReponseList" type="surveyitelios_question_options__c[]"/> 
  <!--aura:attribute name="objInfo" type="surveyitelios_input_types__c" default="{sobjectType : 'surveyitelios_input_types__c'}" /-->

Questions

                     default="{'sobjectType':'surveyitelios_questions__c',

                    'Name': ''}"

                  />     
  <lightning:layout >

    <lightning:layoutItem padding="around-small" size="6">

         <form class="slds-form--stacked">   

            <lightning:input aura:id="Name" label="Question name"

                             name="Name"

                             value="{!v.QuestionLi.Name}"

                             required="true"/>        
             <lightning:input aura:id="input_type_id__c" label="id type"

                             name="input_type_id__c"

                             value="{!v.QuestionLi.input_type_id__c}"

                             required="true"/>

             <lightning:input aura:id="surveyitelios_survey__c" label="id survey"

                             name="surveyitelios_survey__c"

                             value="{!v.QuestionLi.surveyitelios_survey__c}"

                             required="true"/>
</form>

    </lightning:layoutItem>
</lightning:layout>

Les réponses

S.No

            <th scope="col">
                <div class="slds-truncate" title="name">Choix</div>
            </th>
            <th scope="col">
                <div class="slds-truncate" title="Valeur">Valeur</div>
            </th>
            <th scope="col">
                <div class="slds-truncate" title="Question">Id Question</div>
            </th>
        </tr>
    </thead>   
    <tbody>    
        <aura:iteration items="{!v.ReponseList}" var="item" indexVar="index">
            <c:SurveyItelios_dynamicRowItem ReponseInstance="{!item}" rowIndex="{!index}" />
        </aura:iteration>
    </tbody>
</table>
<br/>
<!--Save Button which is call Save js function on click --> 
<button class="slds-button slds-button_brand" onclick="{!c.Save}" style ="margin-left:1%;">Save</button>

Helper Code

({
    createObjectData: function(component, event) {
        var RowItemList = component.get("v.ReponseList");
        RowItemList.push({
            'sobjectType': 'surveyitelios_question_options__c',
            'Name': '',
            'option_value__c': '',
            'question_id__c':''
        });
        component.set("v.ReponseList", RowItemList);
    },

        createObjectDataa: function(component, event) {
        // get the contactList from component and add(push) New Object to List  
        var RowItemListt = component.get("v.QuestionLi");
        RowItemListt.push({
            'sobjectType': 'surveyitelios_questions__c', 
            'Name': '',
            'input_type_id__c': '',
            'surveyitelios_survey__c':''
        });
        component.set("v.QuestionLi", RowItemListt);
    },


    // helper function for check if first Name is not null/blank on save  
    validateRequired: function(component, event) {
        var isValid = true;
        var allContactRows = component.get("v.ReponseList");
        for (var indexVar = 0; indexVar < allContactRows.length; indexVar++) {
            if (allContactRows[indexVar].option_value__c == '') {
                isValid = false;
                alert('Input type Name Can\'t be Blank on Row Number ' + (indexVar + 1));
            }
        }

        return isValid;
    },
      validateRequiredQuestion: function(component, event) {
        var isValid = true;
        var allContactRows = component.get("v.QuestionLi");
        for (var indexVar = 0; indexVar < allContactRows.length; indexVar++) {
            if (allContactRows[indexVar].Name == '') {
                isValid = false;
                alert('Question Name Can\'t be Blank on Row Number ' + (indexVar + 1));
            }
        }

        return isValid;
    },

})

Best Answer

Here are my recommendation:

  1. QuestionLi Attribute is defined as simple object but when it's passed to server, you are assuming it's list of object. Update this attribute as List of object.

  2. As a best practice, your apex method should return some value to identify, possibly String. Keep your DML in try catch block and return exception if any occurs so that you can debug properly.

    public static String saveQuestions (....){

       try{
    
          insert ...
    
          return 'SUCCESS';
    
       catch(Excpetion e){ return e.getMessage();}
    }
    
Related Topic