Today I'm struggling with something I really do not understand. I'm trying to make simple lightning component for creating new record of custom sObject.
Problem appears on the save method. Result which it return is like:
Problem saving record, error: [{"fieldErrors":{},"pageErrors":[]}]
TargetCreator.js:125
Custom error:
{"state":"ERROR","recordId":null,"error":[{"fieldErrors":{},"pageErrors":[]}],"entityApiName":null,"action":{}}
Also force:recordData on initialization return me this:
Record template initialized: undefined
And this is my code:
COMPONENT
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride" access="global" controller="PickListController" >
<aura:attribute name="NewTarget" type="Target__c" />
<aura:attribute name="SimpleNewTarget" type="Object" />
<aura:attribute name="recordError" type="String"/>
<aura:attribute name="objectsNamesValues" type="String[]" />
<aura:attribute name="fieldsNamesValues" type="String[]" default="n/a"/>
<aura:attribute name="dateFieldsValues" type="String[]" default="n/a"/>
<force:recordData aura:id="TargetRecordCreator"
layoutType="FULL"
targetFields="{!v.SimpleNewTarget}"
targetRecord="{!v.NewTarget}"
targetError="{!v.recordError}"
fields="Id,Name,Description__c,Field_API_Name__c,is_Active__c,Object_API_Name__c,Date_Field_API_Name__c"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<div aura:id="editDialog" role="dialog" tabindex="-1" aria-labelledby="header43" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<div class="slds-modal__header">
<h2 class="slds-text-heading--medium">New Target</h2>
</div>
<div class="slds-modal__content slds-p-around--medium slds-grid slds-wrap ">
<lightning:input aura:id="targetName" name="targetName" label="Target Name" required="true" value="{!v.SimpleNewTarget.Name}" placeholder="Enter Target Name" class="slds-size--1-of-1 slds-p-horizontal_x-small"/>
<lightning:input aura:id="Description__c" name="Description__c" label="Description" required="true" value="{!v.SimpleNewTarget.Description__c}" placeholder="Enter description" class="slds-size--1-of-1 slds-p-horizontal_x-small"/>
<!--Object API Name Picklist-->
<lightning:select aura:id="Object_API_Name__c" name="Object_API_Name__c" required="true" label="Object API Name" value="{!v.SimpleNewTarget.Object_API_Name__c}" onchange="{!c.getPicklists}" class="slds-size--1-of-2 slds-p-horizontal_x-small">
<!--Iteration -->
<aura:iteration items="{!v.objectsNamesValues}" var="item">
<option value="{!item}">{!item}</option>
</aura:iteration>
</lightning:select>
<!--Field API Name Picklist-->
<lightning:select aura:id="Field_API_Name__c" name="Field_API_Name__c" required="true" label="Field API Name" value="{!v.SimpleNewTarget.Field_API_Name__c}" class="slds-size--1-of-2 slds-p-horizontal_x-small">
<!--Iteration -->
<aura:iteration items="{!v.fieldsNamesValues}" var="item">
<option value="{!item}">{!item}</option>
</aura:iteration>
</lightning:select>
<!--Date Field API Name Picklist-->
<lightning:select aura:id="Date_Field_API_Name__c" name="Date_Field_API_Name__c" required="true" label="Date Field API Name" value="{!v.SimpleNewTarget.Date_Field_API_Name__c}" class="slds-size--1-of-2 slds-p-horizontal_x-small">
<!--Iteration -->
<aura:iteration items="{!v.dateFieldsValues}" var="item">
<option value="{!item}">{!item}</option>
</aura:iteration>
</lightning:select>
<lightning:select aura:id="Target_Type__c" name="Target_Type__c" value="{!v.SimpleNewTarget.Target_Type__c}" required="true" label="Target Type" class="slds-size--1-of-2 slds-p-horizontal_x-small">
<option>Select Target Type</option>
<option value="Count" >Count</option>
<option value="Sum">Sum</option>
</lightning:select>
<lightning:input aura:id="is_Active__c" type="toggle" checked="{!v.SimpleNewTarget.is_Active__c}" label="is Active?" name="is_Active__c" value="{!v.SimpleNewTarget.is_Active__c}" class="slds-size--1-of-2 slds-p-horizontal_x-small"/>
</div>
<div class="slds-modal__footer">
<lightning:button variant="neutral" label="Cancel" onclick="{!c.cancelDialog}"/>
<lightning:button variant="brand" label="Submit" onclick="{!c.saveRecord}"/>
</div>
</div>
</div>
<div aura:id="overlay" class="slds-backdrop slds-backdrop--open"></div>
<!-- Display Lightning Data Service errors, if any -->
<aura:if isTrue="{!not(empty(v.recordError))}">
<div class="recordError">
<ui:message title="Error" severity="error" closable="true">
{!v.recordError}
</ui:message>
</div>
</aura:if>
</aura:component>
CONTROLLER
({
doInit : function(component, event, helper){
// Prepare a new record from template
component.find("TargetRecordCreator").getNewRecord(
"Target__c", // sObject type (entityAPIName)
null, // recordTypeId
false, // skip cache?
$A.getCallback(function() {
var rec = component.get("v.NewTarget");
var error = component.get("v.recordError");
if(error || (rec === null)) {
console.log("Error initializing record template: " + error);
}
else {
console.log("Record template initialized: " + rec.sobjectType);
}
})
);
var action = component.get("c.getPickListObjectsIntoList");
action.setCallback(this, function(response) {
var list = response.getReturnValue();
component.set("v.objectsNamesValues", list);
})
$A.enqueueAction(action);
},
getPicklists : function(component, event, helper){
helper.getFieldsNames(component, event);
helper.getDatesFields(component, event);
},
cancelDialog : function(component, helper) {
var homeEvt = $A.get("e.force:navigateToObjectHome");
homeEvt.setParams({
"scope": "Target__c"
});
homeEvt.fire();
},
saveRecord : function(component, event, helper) {
var field_api_name = component.find("Field_API_Name__c").get("v.value");
var description = component.find("Description__c").get("v.value");
var object_api_name = component.find("Object_API_Name__c").get("v.value");
var isActive = component.find("is_Active__c").get("v.value");
var targetType = component.find("Target_Type__c").get("v.value");
var name = component.find("targetName").get("v.value");
var date_field_api_name = component.find("Date_Field_API_Name__c").get("v.value");
console.log('field: ' + field_api_name);
console.log('desc: ' + description);
console.log('object: ' + object_api_name);
console.log('isActive: ' + isActive);
console.log('type: ' + targetType);
console.log('targetName: ' + name);
console.log('date: ' + date_field_api_name);
var record = component.get("{!v.SimpleNewTarget}");
console.log("NEW TARGET: " + JSON.stringify(record));
console.log("TargetRecordCreator: " + JSON.stringify(component.find("TargetRecordCreator")));
component.find("TargetRecordCreator").saveRecord(function(saveResult) {
var resultsToast = $A.get("e.force:showToast");
if( ( field_api_name === null || field_api_name === "" || field_api_name === "Select Field API Name") ||
(description === null || description === "") ||
(object_api_name === null || object_api_name === "") ||
(isActive === null || isActive === "") ||
(targetType === null || targetType === "" || targetType === "Select Target Type") ||
(name === null || name === "" ) ||
(date_field_api_name === null || date_field_api_name === "" || date_field_api_name === "Select Date Field API Name")) {
resultsToast.setParams({
"title": "Error",
"message": "Please fill all the required fields"
});
resultsToast.fire();
}else if(saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
// record is saved successfully
resultsToast.setParams({
"title": "Saved",
"message": "The record was saved."
});
resultsToast.fire();
var recId = saveResult.recordId;
var navEvt = $A.get("e.force:navigateToSObject");
navEvt.setParams({
"recordId": recId,
"slideDevName": "related"
});
navEvt.fire();
}
else if (saveResult.state === "INCOMPLETE") {
// handle the incomplete state
resultsToast.setParams({
"title": "Incomplete",
"message": "User is offline, device doesn't support drafts."
});
resultsToast.fire();
} else if (saveResult.state === "ERROR") {
// handle the incomplete state
resultsToast.setParams({
"title": "Error",
"message": "Problem saving record."
});
resultsToast.fire();
// handle the error state
console.log('Problem saving record, error: ' + JSON.stringify(saveResult.error));
console.log('Custom error: ' + JSON.stringify(saveResult));
} else {
console.log('Unknown problem, state: ' + saveResult.state +
', error: ' + JSON.stringify(saveResult.error));
}
});
}
})
HELPER
({
getFieldsNames : function (component, event){
var action = component.get("c.getPickListFieldsIntoList");
action.setParams({ ObjectApiName: component.find('Object_API_Name__c').get("v.value")});
action.setCallback(this, function(response) {
var list = response.getReturnValue();
component.set("v.fieldsNamesValues", list);
})
$A.enqueueAction(action);
},
getDatesFields : function (component, event){
var action = component.get("c.getPickListDatesIntoList");
action.setParams({ ObjectApiName: component.find('Object_API_Name__c').get("v.value")});
action.setCallback(this, function(response) {
var list = response.getReturnValue();
component.set("v.dateFieldsValues", list);
})
$A.enqueueAction(action);
}
})
Best Answer
Problem solved. Somewhere during the merge with master branch, system-administrator profile somehow changed two fields of Target__c to be not editable. Code is 100% fine. Just another problem with Salesforce debugging...