[SalesForce] Unable to save a record using LDS

I use lightning data service method SaveRecord to create a record of type BoatReview__c. The boatReview__c object has following fields:

enter image description here

I only populate Name and comment__C field using a form on my component. I also use a helper function to populate the value of Boat__c with parent object Id. I am not sure why there is boat__c and boat__r(two variables). I show you below when I populate the boat__c value only.Before executing the LDS saveRecord method , below is how my JSON looks like:

{
  "apiName": "BoatReview__c",
  "childRelationships": {},
  "fields": {
    "Boat__c": "a021I000003VMuVQAW",
    "Boat__r": {
      "displayValue": null,
      "value": null
    },
    "CreatedBy": {
      "displayValue": null,
      "value": null
    },
    "LastModifiedBy": {
      "displayValue": null,
      "value": null
    },
    "Name": {
      "displayValue": null,
      "value": null
    },
    "Id": {
      "value": null
    },
    "Comment__c": {
      "value": null
    }
  },
  "id": null,
  "recordTypeInfo": null,
  "Name": "test",
  "Comment__c": "<p>test</p>"
}

I also try populating boat__c and boat__r. Which gives me below JSON. I have an attr in my component which has a value for boat__c object that I using to populate.

{
  "apiName": "BoatReview__c",
  "childRelationships": {},
  "fields": {
    "Boat__c": "a021I000003VMuVQAW",
    "Boat__r": {
      "BoatType__r": {
        "Id": "a011I00000Amwb2QAB",
        "Name": "Ski Boat"
      },
      "Contact__r": {
        "Email": "rachel@trailheadboats.com",
        "HomePhone": null,
        "Id": "0031I000008E0itQAC",
        "Name": "Rachel King"
      },
      "Description__c": null,
      "Id": "a021I000003VMuVQAW",
      "Length__c": 15,
      "Name": "The Old Man and the Sea",
      "Picture__c": "/resource/Sailboats/skiboat2.png",
      "Price__c": 55000,
      "SystemModstamp": "2017-12-07T02:38:27.000Z"
    },
    "CreatedBy": {
      "displayValue": null,
      "value": null
    },
    "LastModifiedBy": {
      "displayValue": null,
      "value": null
    },
    "Name": {
      "displayValue": null,
      "value": null
    },
    "Id": {
      "value": null
    },
    "Comment__c": {
      "value": null
    }
  },
  "id": null,
  "recordTypeInfo": null,
  "Name": "st",
  "Comment__c": "<p>test</p>"
}

However the saveResult of recordData.saveRecord($A.getCallback(function(saveResult) returns an Error. I try to investigate the error but it prints undefined. Any idea what is wrong?

        for (var i = 0; i < saveResult.error.length; i++) {
            errMsg += saveResult.error[i].message + "\n";
            console.log('errMsg is *** ' + errMsg);
        }
        component.set("v.recordError", errMsg);

errMsg prints undefined.

Component:

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" description="AddBoatReview">
<aura:attribute name="boat" type="Boat__c"/>
<aura:attribute name="boatReview" type="BoatReview__c" access="private"
                default="{'sobjectType':'BoatReview__c', 'Name':'', 'Comment__c':''}"/>
    <aura:attribute name="record" type="BoatReview__c" access="private"/>
    <aura:attribute name="recordError" type="String" access="private"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <force:recordData aura:id="service"
                      fields="Id,Name,Comment__c"
                      targetError="{!v.recordError}"
                      targetRecord="{!v.record}"
                      targetFields="{!v.boatReview}"
                      recordUpdated="{!c.onRecordUpdated}"/>

    <form class="slds-form--stacked">
        <lightning:input label="Title"
                         value="{!v.boatReview.Name}"/>
        <lightning:inputRichText title="Description"
                         value="{!v.boatReview.Comment__c}"/>
        <lightning:button label="Submit"
                          class="slds-m-top--medium"
                          iconName="utility:save"
                          variant="brand"
                          onclick="{!c.onSave}"/>
    </form>

    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError">
                {!v.recordError}</div>
    </aura:if>
</aura:component>

Controller:

({
    doInit:function (component,event,helper) {
        var eventParams = event.getParams();
        helper.onInit(component,eventParams);
    },
    onRecordUpdated:function (component,event,helper) {

    },
    onSave:function (component,event,helper) {
        console.log('Enters the Save method');
        var recordData = component.find("service");
        //component.set("v.boatReview.Boat__c", component.get("v.boat").Id);
        console.log('v.boatReview ' + JSON.stringify(component.get("v.boatReview")));
        recordData.saveRecord($A.getCallback(function(saveResult) {
            console.log('Enter saverecord Funtion ' + saveResult.state);
            if (saveResult.state === "ERROR") {
                var errMsg = "";
                // saveResult.error is an array of errors,
                // so collect all errors into one message
                for (var i = 0; i < saveResult.error.length; i++) {
                    errMsg += saveResult.error[i].message + "\n";
                    console.log('errMsg is *** ' + errMsg);
                }
                component.set("v.recordError", errMsg);
                console.log('Saved Error ' + errMsg);
            } else {
                console.log('Saved Success ');
                component.set("v.recordError", "");
                var toastEvent = $A.get("e.force:showToast");
                toastEvent.setParams({
                    "title": "Success!",
                    "message": "The record has been Saved successfully."
                });
                toastEvent.fire();
            }
        }));
    }


})

Helper:

({

    onInit: function(component,event){

       console.log('onInit Helper funciton in ' + event.changeType);
        console.log('component value is ' + JSON.stringify(component.get("v.boat")));
        console.log('component value is ' + JSON.stringify(component.get("v.boatReview")));
        component.find("service").getNewRecord(
            "BoatReview__c", // sObject type (objectApiName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.record");
                var error = component.get("v.recordError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                    return;
                }
                console.log("Record template initialized: " + JSON.stringify(rec));
                rec.fields.Boat__r = component.get("v.boat");
                rec.fields.Boat__c = component.get("v.boat").Id;
                component.set("v.boatReview",rec);
                console.log("BoatReview template ----> : " + JSON.stringify(component.get("v.boatReview")));
            })
        );
    }


})

Best Answer

The problem was I was assigning rec to boatreview in my helper function :

component.set("v.boatReview",rec);

This is not correct for some reason. I removed this line and I was able to save the record. It seems like I should not assign targetRecord object to targetField object directly. However my intention was to populate the parent Object(boat__C) id in target field object -boatReview.

Related Topic