4

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")));
            })
        );
    }


})
  • Boat__c is the primary key, and stores the id value of the lookup record. Boat__r is the relationship name, and stores the data of the related object when its retrieved via soql or another method. Trying to access Boat__c.Name would fail, but Boat__r.Name would be successful. – battery.cord Dec 27 '17 at 16:17
  • You should add the code you use to actually save the record, I think theres a check in your error handling thats missing (Checking isSuccess or an equivalent before trying to access the array of errors) – battery.cord Dec 27 '17 at 16:18
  • Added the controller code which tries to save the record. The helper function populates the parent record details on initialization. I have the parent attr - boat , having the values. – Arnold Dec 27 '17 at 16:25
  • @battery.cord Please check my answer. However I am trying to see how can I populate the parent Object Id in init - I tried this - component.set(("v.boatReview").boat__c,component.get("v.boat").Id); but that dint work out. – Arnold Dec 27 '17 at 17:57
1

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.

  • 2
    You should only ever need to use one or the other of targetRecord and targetFields. They’re always the same record, but it different formats - targetRecord has more complete displayValues and recordType info, but the syntax of targetFields is a lot simpler to reference directly in a component. You’d never want to set the value of one from the other. – Carolyn Grabill Jan 4 '18 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.