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
Nihar ANihar A 

Best way to create Sobject records in aura handler or use the data that is returned from apex controller in Lightning?

I am trying to convert a Custom JS button in classic into Lightning action. it is a button on account object. The logic in classic looks something like this:

var a= account.id;
var b = account.type;
var c = account.recordType;

if(a != "" && b == //somevalue && c== somevalue){
//do something;
}
else{
//do something;
}

If I want to convert this logic into lightning whats the best way to do it. As I am using account attributes to decide on the logic that I am going to excute I need access to few account record's details.
Approach I used:

Component Code :

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId" controller="ApexController">
    <aura:handler name="init" value="{!this}" action="{!c.JsHandler}" />
    <aura:attribute name="recordId" type="Id" />
  <aura:attribute name="acc" type="Account"
         default="{ 'sobjectType': 'Account',
                           'Name': '',
                         'Type': '',
                           'RecordType.Name':''     
                       }"/>
</aura:component>

Handler:

var action =  component.get("c.getData");
        action.setParams({"accountId": component.get("v.recordId")});
        action.setCallback(this, function(response){
            component.set("v.acc",response.getReturnValue());
            var acctType = component.get("v.acc.Type");
            var RecordType = component.get("v.acc.RecordType.Name");
            var acctName = component.get("v.acc.Name");
            var acctId = component.get("v.acc.Id");
          // same logic as in the above classic JS button and decide what to do.

Apex Controller:
public class GetNeededData {
    @AuraEnabled
    public static account getData(Id accountId){
        return [select Name,Type,RecordType.name from Account where Id = :accountId];
    }
}

I have a few questions in this implementation:
1) Is this the best possible way to do this or Are there any patterns that I am missing?
2) To access the data returned from the controller, should I declare an account attribute "acc" in the component and use it in the handler to access data from controller OR can I directly create an account record in handler and assign the returned result to it. If yes , how.
3) And if I want to create a case in one of the if else logic , Should I first create a Case attribute in the component and then assign different values in handler and then push that data to controller and Insert the data in controller or Can I use Ajax Toolkit's sobject.connection.create to push the data directly to SF insetad of using a controller.

Thanks in Advance.

Nihar.

 


 
Dogan Turkcan 9Dogan Turkcan 9
Hi,
 If this solves your problem, please mark it as the answer.

First Of All if you use force:hasRecordId no need to initialize    <aura:attribute name="recordId" type="Id" />.
1) For the first question it is ok.
2)You can do both 2 ways.
1st one
var myAcc=response.getReturnValue();
alert(myAcc.Name);
alert(myAcc.RecordType.Name);
2nd one
component.set("v.acc", response.getReturnValue());
alert(component.get("v.acc.RecordType.Name"));


3) For Creating Case in Lightning component:
  <aura:attribute name="mynewCase" type="Case" default="{ 'sobjectType': 'Case',
                           'AccountId': '',
                         'AssetId': '',
                           'RecordTypeId':''     
                       }"/>

Javascript Controller:

component.set("v.mynewCase.AccountId","xxxxxxxxx");
component.set("v.mynewCase.AssetId","yyyyyyy");
component.set("v.mynewCase.Description","asdfasdfasdfzzzzzzz");
.
.
.
.
//Call Lightning Controller
var action = component.get("c.insertCase");
        action.setParams({newCase:component.get("v.mynewCase")});
        var self = this;
        action.setCallback(this, function(actionResult) {
            var result=actionResult.getReturnValue()[0];
            var resultMessage=actionResult.getReturnValue()[1];
                });
                $A.enqueueAction(action);

//Lightning Controller

@AuraEnabled
    @RemoteAction
    public static List <String> insertCase(Case newCase)
    {
        String ErrorMessage='';
        String ErrorCode='';
        List <String> ReturnString=new List<String>();
        try 
        {    
            
                upsert newCase;  
                ErrorCode='0';
                ErrorMessage='Success'; 
                ReturnString.add(ErrorCode);
                ReturnString.add(ErrorMessage);
                return ReturnString;
           
            
        }
        catch(DmlException e) 
        {
            ErrorCode='1';  
            ApexPages.Message msg = new ApexPages.Message(Apexpages.Severity.ERROR, e.getdmlMessage(0) );
            ErrorMessage=e.getMessage();
            ReturnString.add(ErrorCode);
            ReturnString.add(msg.getDetail());
            return ReturnString;
        } 
        catch(Exception e) 
        {
            ErrorCode='1';  
            ApexPages.Message msg = new ApexPages.Message(Apexpages.Severity.ERROR, e.getMessage() );
            ErrorMessage=e.getMessage();
            ReturnString.add(ErrorCode);
            ReturnString.add(msg.getDetail());
            return ReturnString;
        } 
        finally 
        {
            // Perform some clean up.
        }
        
        
    }
Nihar ANihar A
Hi Dogan,

Thank you for the inputs. I have a couple of questions:

1) In the answer to the second question: If I directly create an account variable in JS controller like var myAcc in you answer. Is it going to directly associate with the account data type that is being returned by the Apex controller and I can access myAcc.name,myAcc.Id directly?

2) While creating a case attribute in component, should I initialize all the case fields that I intend to use as null and set those values in JS handler before pushing them onto Apex controller to insert into DB. OR can i just initialize the attribute without any field values and assign the values that I need in JS handler and push it to Apex controller.

Thanks in advance.

Nihar.
Dogan Turkcan 9Dogan Turkcan 9
Hi,
 If this solves your problem, please mark it as the answer.

1) Yes you can access, if you add those fields to selection in apex controller. 
2) I guess you don't need to initialize all case fields in the component section, sobjectType may be enough but i didnt test it. 

Also without initializing on component you can do it in js controller.

 var newCaseRecord = {sobjectType:"Case", 
                                   AccountId:"65465465464",
                                   CaseId:"65465465454",
                                   Description:"this is description"    
                                       };