function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Emilien Guichard 40Emilien Guichard 40 

Trailhead module Lightning Data Service Basics - Creating Records

Hi,
I am following the Trailhead module  Lightning Data Service Basics, at the Creating Records step when trying to create a new record I am getting the followinh error:
 
TypeError: Action failed: force:record$controller$getNewRecord [type error on parameter callback: expected Function, found boolean]
Callback failed: serviceComponent://ui.flexipage.components.page.FlexipageController/ACTION$getPage
Here is my code
ldsNewRecord.cmp
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">

<aura:attribute name="newContact" type="Object"/>
<aura:attribute name="simpleNewContact" type="Object"/>
<aura:attribute name="newContactError" type="String"/>

<force:recordData aura:id="contactRecordCreator"
    layoutType="FULL"
    targetRecord="{!v.newContact}"
    targetFields="{!v.simpleNewContact}"
    targetError="{!v.newContactError}"
    />

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <!-- Display a header -->
    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">Create Contact</p>
    </div>

    <!-- Display Lightning Data Service errors -->
    <aura:if isTrue="{!not(empty(v.newContactError))}">
        <div class="recordError">
            <ui:message title="Error" severity="error" closable="true">
                {!v.newContactError}
            </ui:message>
        </div>
    </aura:if>

    <!-- Display the new contact form -->
    <div class="slds-form--stacked">
        <lightning:input aura:id="contactField" name="firstName" label="First Name"
                         value="{!v.simpleNewContact.FirstName}" required="true"/>
      
        <lightning:input aura:id="contactField" name="lastname" label="Last Name"
                      value="{!v.simpleNewContact.LastName}" required="true"/>
                
        <lightning:input aura:id="contactField" name="title" label="Title"
                      value="{!v.simpleNewContact.Title}" />
                      
        <lightning:button label="Save contact" onclick="{!c.handleSaveContact}"
                   variant="brand" class="slds-m-top--medium"/>
   </div>

</aura:component>
ldsNewRecordController.js
({
    doInit: function(component, event, helper) {
        // Prepare a new record from template
        component.find("contactRecordCreator").getNewRecord(
            "Contact", // sObject type (entityAPIName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.newContact");
                var error = component.get("v.newContactError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                }
                else {
                    console.log("Record template initialized: " + rec.sobjectType);
                }
            })
        );
    },

    handleSaveContact: function(component, event, helper) {
        if(helper.validateContactForm(component)) {
            component.set("v.simpleNewContact.AccountId", component.get("v.recordId"));
            component.find("contactRecordCreator").saveRecord(function(saveResult) {
                if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                    // record is saved successfully
                    var resultsToast = $A.get("e.force:showToast");
                    resultsToast.setParams({
                        "title": "Saved",
                        "message": "The record was saved."
                    });
                    resultsToast.fire();

                } else if (saveResult.state === "INCOMPLETE") {
                    // handle the incomplete state
                    console.log("User is offline, device doesn't support drafts.");
                } else if (saveResult.state === "ERROR") {
                    // handle the error state
                    console.log('Problem saving contact, error: ' + 
                                 JSON.stringify(saveResult.error));
                } else {
                    console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
                }
            });
        }
    }
})
Could please assist ?
Thanks for your help.


 
Best Answer chosen by Emilien Guichard 40
Alain CabonAlain Cabon
Hi,

This is not the challenge but the given pattern and it works fine. It lacks just the helper part.

COMPONENT (copy/paste)
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">

<aura:attribute name="newContact" type="Object"/>
<aura:attribute name="simpleNewContact" type="Object"/>
<aura:attribute name="newContactError" type="String"/>

<force:recordData aura:id="contactRecordCreator"
    layoutType="FULL"
    targetRecord="{!v.newContact}"
    targetFields ="{!v.simpleNewContact}"
    targetError="{!v.newContactError}"
    />

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <!-- Display a header -->
    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">Create Contact</p>
    </div>

    <!-- Display Lightning Data Service errors -->
    <aura:if isTrue="{!not(empty(v.newContactError))}">
        <div class="recordError">
            <ui:message title="Error" severity="error" closable="true">
                {!v.newContactError}
            </ui:message>
        </div>
    </aura:if>

    <!-- Display the new contact form -->
    <div class="slds-form--stacked">
        <lightning:input aura:id="contactField" name="firstName" label="First Name"
                         value="{!v.simpleNewContact.FirstName}" required="true"/>
      
        <lightning:input aura:id="contactField" name="lastname" label="Last Name"
                      value="{!v.simpleNewContact.LastName}" required="true"/>
                
        <lightning:input aura:id="contactField" name="title" label="Title"
                      value="{!v.simpleNewContact.Title}" />
                      
        <lightning:button label="Save contact" onclick="{!c.handleSaveContact}"
                   variant="brand" class="slds-m-top--medium"/>
   </div>

</aura:component>
CONTROLLER (copy/paste):
({
    doInit: function(component, event, helper) {
        // Prepare a new record from template
        component.find("contactRecordCreator").getNewRecord(
            "Contact", // sObject type (entityAPIName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.newContact");
                var error = component.get("v.newContactError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                }
                else {
                    console.log("Record template initialized: " + rec.sobjectType);
                }
            })
        );
    },

    handleSaveContact: function(component, event, helper) {
        if(helper.validateContactForm(component)) {
            component.set("v.simpleNewContact.AccountId", component.get("v.recordId"));
            component.find("contactRecordCreator").saveRecord(function(saveResult) {
                if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                    // record is saved successfully
                    var resultsToast = $A.get("e.force:showToast");
                    resultsToast.setParams({
                        "title": "Saved",
                        "message": "The record was saved."
                    });
                    resultsToast.fire();

                } else if (saveResult.state === "INCOMPLETE") {
                    // handle the incomplete state
                    console.log("User is offline, device doesn't support drafts.");
                } else if (saveResult.state === "ERROR") {
                    // handle the error state
                    console.log('Problem saving contact, error: ' + 
                } else {
                    console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
                }
            });
        }
    }
})

and the HELPER for validateContactForm (always true here)
 
({
	helperMethod : function() {
		
	},
    validateContactForm:function(component) {
       return true;
    } 
})

Page Lightning of Account with the two new components : the challenge is the component "Edit Account" (not CREATE CONTACT just above)

User-added image

User-added image

The given pattern works fine

Regards

Alain

All Answers

Alain CabonAlain Cabon
Hi,

This is not the challenge but the given pattern and it works fine. It lacks just the helper part.

COMPONENT (copy/paste)
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">

<aura:attribute name="newContact" type="Object"/>
<aura:attribute name="simpleNewContact" type="Object"/>
<aura:attribute name="newContactError" type="String"/>

<force:recordData aura:id="contactRecordCreator"
    layoutType="FULL"
    targetRecord="{!v.newContact}"
    targetFields ="{!v.simpleNewContact}"
    targetError="{!v.newContactError}"
    />

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <!-- Display a header -->
    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">Create Contact</p>
    </div>

    <!-- Display Lightning Data Service errors -->
    <aura:if isTrue="{!not(empty(v.newContactError))}">
        <div class="recordError">
            <ui:message title="Error" severity="error" closable="true">
                {!v.newContactError}
            </ui:message>
        </div>
    </aura:if>

    <!-- Display the new contact form -->
    <div class="slds-form--stacked">
        <lightning:input aura:id="contactField" name="firstName" label="First Name"
                         value="{!v.simpleNewContact.FirstName}" required="true"/>
      
        <lightning:input aura:id="contactField" name="lastname" label="Last Name"
                      value="{!v.simpleNewContact.LastName}" required="true"/>
                
        <lightning:input aura:id="contactField" name="title" label="Title"
                      value="{!v.simpleNewContact.Title}" />
                      
        <lightning:button label="Save contact" onclick="{!c.handleSaveContact}"
                   variant="brand" class="slds-m-top--medium"/>
   </div>

</aura:component>
CONTROLLER (copy/paste):
({
    doInit: function(component, event, helper) {
        // Prepare a new record from template
        component.find("contactRecordCreator").getNewRecord(
            "Contact", // sObject type (entityAPIName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.newContact");
                var error = component.get("v.newContactError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                }
                else {
                    console.log("Record template initialized: " + rec.sobjectType);
                }
            })
        );
    },

    handleSaveContact: function(component, event, helper) {
        if(helper.validateContactForm(component)) {
            component.set("v.simpleNewContact.AccountId", component.get("v.recordId"));
            component.find("contactRecordCreator").saveRecord(function(saveResult) {
                if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                    // record is saved successfully
                    var resultsToast = $A.get("e.force:showToast");
                    resultsToast.setParams({
                        "title": "Saved",
                        "message": "The record was saved."
                    });
                    resultsToast.fire();

                } else if (saveResult.state === "INCOMPLETE") {
                    // handle the incomplete state
                    console.log("User is offline, device doesn't support drafts.");
                } else if (saveResult.state === "ERROR") {
                    // handle the error state
                    console.log('Problem saving contact, error: ' + 
                } else {
                    console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
                }
            });
        }
    }
})

and the HELPER for validateContactForm (always true here)
 
({
	helperMethod : function() {
		
	},
    validateContactForm:function(component) {
       return true;
    } 
})

Page Lightning of Account with the two new components : the challenge is the component "Edit Account" (not CREATE CONTACT just above)

User-added image

User-added image

The given pattern works fine

Regards

Alain
This was selected as the best answer
Alain CabonAlain Cabon
} else if (saveResult.state === "ERROR") {
                   // handle the error state
                  console.log('Problem saving contact, error: ' +  JSON.stringify(saveResult.error));
  }
I used a toast and I removed it with the end the console.log above after the copy/paste here.

Alain