I'm trying to clone an Opportunity record with certain values changed.

Below is my code (component will be launched from Lightning component action).

My Component Markup

<aura:component implements="flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader,force:hasRecordId" 
                controller="OpportunityClonner" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="recordId" type="String" access="PUBLIC"/> 
    <aura:attribute name="clonedRecId" type="String" access="PUBLIC"/>

    <aura:attribute name="newOpp" type="Opportunity"/>
    <aura:attribute name="simpleNewOpp" type="Opportunity"/>
    <aura:attribute name="newOppError" type="String"/>

    <aura:if isTrue="{!not(empty(v.newOppError))}">
        <div class="recordError">
    <div aura:id="spinner">
        <lightning:spinner alternativeText="Loading" size="large" />
        <div class="modal-header slds-modal__header">
            <h2 class="title slds-text-heading--medium">Clone Opportunity</h2>

        <div class="modal-body scrollable slds-modal__content slds-scrollable_y">
            <force:recordData aura:id="clonnedRec"
                              targetFields ="{!v.simpleNewOpp}" 


    <div class="slds-float--right">
        <lightning:button label="Cancel" onclick="{!c.cancel}"/>
        <lightning:button label="Save" onclick="{!c.save}" variant="brand"/>

My JS controller code:

    doInit: function(component, event, helper) {
        console.log('rec: '+component.get("v.recordId"));

    handleRecordUpdated: function(component, event, helper) {
        var eventParams = event.getParams();
        if(eventParams.changeType === "LOADED") {
            // record is loaded (render other component which needs record data value)
            console.log("Record is loaded successfully.");

            var opp = component.get("v.simpleNewOpp");
            opp.Originated_From__c = component.get("v.recordId");
            opp.Id = null;

            //console.log('new opp: '+JSON.stringify(component.get("v.newOpp")));
            //console.log('simpleNewOpp: '+JSON.stringify(component.get("v.simpleNewOpp")));

            $A.util.addClass(component.find("spinner"), 'slds-hide');
        } else if(eventParams.changeType === "CHANGED") {
            // record is changed
        } else if(eventParams.changeType === "REMOVED") {
            // record is deleted
        } else if(eventParams.changeType === "ERROR") {
            // there’s an error while loading, saving, or deleting the record

    save : function(component, event, helper) {
        component.find("clonnedRec").saveRecord($A.getCallback(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                console.log("Save completed successfully.");
            } else if (saveResult.state === "INCOMPLETE") {
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
                console.log('Problem saving record, error: ' + 
            } else {
                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));


        cancel : function(component, event, helper) {

I'm setting Originated_From__c value just after loading the data, and clearing record Id, assuming it will enable me to clone the Opportunity.

But it seems does not do clonning, but saving the same record. Appreciate any help on this.


  • 1
    Wouldnt it be easier to create a "Clone" Button, which in the backend would create your new opportunity, with the same fields as the current record and load a form with the newly created record using force:recordData, rather than trying to set your already defined recordId attribute to null, in order to try and trigger a create new record with the changed data in your form? – glls Jun 9 '18 at 17:03

I believe the reason why your approach is not working might be because when you load the force:recordData with the record ID and then try to change the assigned id dynamically client side, the binding might still exists with the previous record ID. I would suggest you rather clone the record server side, and invoke it in the form afterwards for modification.

  • Thanks @glls I did try that approach too (getting all writable Fields to SQL and set the object on force: recordData, but for some reason UI seems not refreshing, stays blank even if I used reload method call. – Pasan Eeriyagama Jun 9 '18 at 20:37
  • 1
    if you dont show us your code, its kind of hard to guess what you did wrong in regards to this approach – glls Jun 9 '18 at 20:40

As the force:recordData is using for Provides the ability to create, read, update, and delete Salesforce records in Lightning. I don't think you can clone record with this component. You may just use the Apex controller with SObject.clone() method and with lighting:input or ui:input in Lightning component.

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.