+ Start a Discussion
Mayank_SareenMayank_Sareen 
Hi all ,
 
I am confused with when exactly do we use an indirect lookup, a lookup and an external lookup relationship. Why cant we use just a lookup relationship for every case.

Thanks
Mayank. 
Best Answer chosen by Mayank_Sareen
Shubham NandwanaShubham Nandwana
Hi Mayank,
Salesforce provides standard, custom and also supports external objects. 
External objects are similar to custom objects, but external object record data is stored outside your Salesforce organization. For example, perhaps you have data that’s stored on premises in an enterprise resource planning (ERP) system. Instead of copying the data into your org, you can use external objects to access the data in real time via web service callouts. (https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_external_objects.htm)

External objects support standard lookup relationships, which use the 18-character Salesforce record IDs to associate related records with each other. However, data that are stored outside your Salesforce org often doesn’t contain those record IDs. Therefore, two special types of lookup relationships are available for external objects: external lookups and indirect lookups. See ”External Object Relationships” in the Salesforce Help for details.

External lookup relationship
External lookup relationship links a child standard, custom, or external object to a parent external object. The values of the standard External ID field on the parent external object are matched against the values of the external lookup relationship field. For a child external object, the values of the external lookup relationship field come from the specified External Column Name.
In External lookup relationship, External Object will be the parent.

Indirect lookup relationship
Indirect lookup relationship links a child external object to a parent standard or custom object. You select a custom unique, external ID field on the parent object to match against the child’s indirect lookup relationship field, whose values are determined by the specified External Column Name.
In Indirect lookup relationship, Salesforce standard or custom object will be the parent and External Object will be the child.

Lookup relationship
The relationship between the two internal objects is a lookup relationship. A lookup relationship essentially links two objects together so that you can “look up” one object from the related items on another object.

Please mark it as best answer if my answer helps you.
Shubham Nandwana.
AppPerfect Corp.
salesforce@appperfect.com
408-252-4100
http://www.appperfect.com/services/salesforce/
Salesforce Development & Operations Experts
Dnyanesh SableDnyanesh Sable 
Please give me solution. in below i have created componets and it's Code.
campingListForm.cmp
<aura:component > 
    <aura:attribute name="newItem" type="Camping_Item__c"
                    default="{ 'sobjectType': 'Camping_Item__c',
                             'Name': '',
                             'Quantity__c': 0,
                             'Price__c': 0,
                             'Packed__c': false }"/>
    <aura:registerEvent name="addItem" type="c:addItemEvent"/>
     
    <form class="slds-form--stacked">
        
        <div class="slds-form-element slds-is-required">
            <div class="slds-form-element__control">
                <ui:inputText aura:id="itemname" label="Name"
                              class="slds-input"
                              labelClass="slds-form-element__label"
                              value="{!v.newItem.Name}"
                              required="true"/> 
            </div>
        </div>
        
        <div class="slds-form-element slds-is-required">
            <div class="slds-form-element__control">
                <ui:inputNumber aura:id="quantity" label="Quantity"
                                class="slds-input"
                                labelClass="slds-form-element__label"
                                value="{!v.newItem.Quantity__c}"
                                required="true"/>
                
            </div>
        </div>
        
        <div class="slds-form-element">
            <div class="slds-form-element__control">
                <ui:inputCurrency aura:id="price" label="Price"
                                  class="slds-input"
                                  labelClass="slds-form-element__label"
                                  value="{!v.newItem.Price__c}"
                                  />
            </div>
        </div>
        
        <div class="slds-form-element">
            <ui:inputCheckbox aura:id="packed" label="Packed?"
                              class="slds-checkbox"
                              labelClass="slds-form-element__label"
                              value="{!v.newItem.Packed__c}"/>
        </div>
        
        <div class="slds-form-element">
            <ui:button label="Create Camping Item"
                       class="slds-button slds-button--brand"
                       press="{!c.submitForm}"/>
        </div>
        
    </form>
     
</aura:component>

campingListFormController.js
({
    
    submitForm: function(component, event, helper) {    
    if(helper.validateItemForm(component)){
         
        var newItem = component.get("v.newItem");
        helper.createItem(component, newItem);
    }  
        } 
})

campingListFormHelper.js
({
 addItem: function(component, newItem) {
    var addItem = component.getItem("addItem");
    addItem.setParams({ "item": item });
    addItem.fire();
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0,
                    'Price__c': 0,
                    'Packed__c': false } );
},
    

        validateItemForm: function(component) {
        
              // Simplistic error checking
        var validItem = true;

        // Name must not be blank
        var nameField = component.find("itemname");
        var itemname = nameField.get("v.value");
        if ($A.util.isEmpty(itemname)){
            validItem = false;
            nameField.set("v.errors", [{message:"Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        
        // Quantity must not be blank
        var quantityField = component.find("quantity");
        var quantity = nameField.get("v.value");
        if ($A.util.isEmpty(quantity)){
            validItem = false;
            quantityField.set("v.errors", [{message:"Quantity can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }
        // Price must not be blank
        var priceField = component.find("price");
        var price = priceField.get("v.value");
        if ($A.util.isEmpty(price)){
            validItem = false;
            priceField.set("v.errors", [{message:"Price can't be blank."}]);
        }
        else {
            quantityField.set("v.errors", null);
        }
            return (validItem);

    }
})

addItemEvent.evt
<aura:event type="COMPONENT">
    <aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>




 
Best Answer chosen by Dnyanesh Sable
Ajay K DubediAjay K Dubedi
Hi Dnyanesh,
Try the following codes:

1. campingListForm.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<aura:attribute name="newItem" type="Camping_Item__c" default="{ 'sobjectType': 'Camping_Item__c',
                                                               'Name': '',
                                                               'Quantity__c': 0,                                          
                                                               'Price__c': 0,
                                                               'Packed__c': false }"/>
<aura:registerEvent name="addItem" type="c:addItemEvent"/>
<lightning:layout >
    <lightning:layoutItem padding="around-small" size="6">
        <div aria-labelledby="newcampaignform">
            <fieldset class="slds-box slds-theme--default slds-container--small">
                <legend id="newcampaignform" class="slds-text-heading--small slds-p-vertical--medium">
                    Add Campaign List
                </legend>
                <form class="slds-form--stacked">
                    <lightning:input aura:id="campaignform" label="Campaign Item Name"
                                     name="campaignitemname"
                                     value="{!v.newItem.Name}"
                                     required="true"/>
                    <lightning:input type="number" aura:id="expenseform" label="Quantity"
                                     name="campaignitemprice"
                                     min="1"
                                     formatter="number"
                                     step="0.1"
                                     value="{!v.newItem.Quantity__c}"
                                     messageWhenRangeUnderflow="Enter quantity that's at least 1."/>
                    <lightning:input type="number" aura:id="expenseform" label="Price"
                                     name="campaignitemprice"
                                     min="0.1"
                                     formatter="currency"
                                     step="0.01"
                                     value="{!v.newItem.Price__c}"
                                     messageWhenRangeUnderflow="Enter an amount that's at least $0.10."/>
                    <lightning:input type="checkbox" aura:id="expenseform" label="Packed?"
                                     name="expreimbursed"
                                     checked="{!v.newItem.Packed__c}"/>
                    <lightning:button label="Create Camping" class="slds-m-top--medium"
                                      variant="brand" onclick="{!c.clickCreateItem}"/>
                </form>
            </fieldset>
        </div>
        
    </lightning:layoutItem>
</lightning:layout>
</aura:component>
2. campingListFormController.js
({

submitForm: function(component, event, helper) {    
if(helper.validateItemForm(component)){
    // Create the new item
    var newItem = component.get("v.newItem");
    helper.createItem(component, newItem);
}
    
    }

})
3. campingListFormHelper.js
({
addItem: function(component, newItem) {
var addItem = component.getItem("addItem");
addItem.setParams({ "item": item });
addItem.fire();
    component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
            'Name': '',
            'Quantity__c': 0,
            'Price__c': 0,
            'Packed__c': false } );
},


validateItemForm: function(component) {

      // Simplistic error checking
var validItem = true;

// Name must not be blank
var nameField = component.find("itemname");
var itemname = nameField.get("v.value");
if ($A.util.isEmpty(itemname)){
    validItem = false;
    nameField.set("v.errors", [{message:"Item name can't be blank."}]);
}
else {
    nameField.set("v.errors", null);
}

// Quantity must not be blank
var quantityField = component.find("quantity");
var quantity = nameField.get("v.value");
if ($A.util.isEmpty(quantity)){
    validItem = false;
    quantityField.set("v.errors", [{message:"Quantity can't be blank."}]);
}
else {
    quantityField.set("v.errors", null);
}
// Price must not be blank
var priceField = component.find("price");
var price = priceField.get("v.value");
if ($A.util.isEmpty(price)){
    validItem = false;
    priceField.set("v.errors", [{message:"Price can't be blank."}]);
}
else {
    quantityField.set("v.errors", null);
}
    return (validItem);

}
})
4. addItemEvent.evt
<aura:event type="COMPONENT">
<aura:attribute name="item" type="Camping_Item__c"/>
</aura:event>
I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi    



 
d3developerd3developer 

Okay folks, I know this is a n00b question but I can't remember if or how to initialize a string with a set of arguments.

 

What I want to do is something like this

 

 

List<String> alphabet = { 'a' , 'b' , 'c' ...  };

 

How can I do this?

 

Best Answer chosen by Admin (Salesforce Developers) 
Jeremy.NottinghJeremy.Nottingh

 

List<String> alphabet = new list<String> { 'a' , 'b' , 'c' ...  };

 That should do ya.

 

EmilyMEmilyM 
I'm getting the following error when attempting to convert a Lead:

System.DmlException: ConvertLead failed. First exception on row 0; first error:
INVALID_STATUS, invalid convertedStatus: Closed - Converted: []

I have determined that this is happening because I have more than one converted LeadStatus.  Different Lead RecordTypes have corresponding Lead Processes associated to them, each one using a different converted LeadStatus.

The code I have to pick LeadStatus is:

LeadStatus convertStatus = [Select Id, MasterLabel from LeadStatus  where IsConverted=true limit 1];

Obviously, this just picks the first available converted LeadStatus, which for some RecordTypes is not the appropriate one.

Could someone please point me to a code sample that does a smarter
LeadStatus selection?

 

Also, I'd like to understand why convertLead started failing with this error in the last month or so, since everything else stayed the same.  Someone suggested in the forum that there were several issues after the Spring 12 release.
Thanks!
Best Answer chosen by Admin (Salesforce Developers) 
Marty Y. ChangMarty Y. Chang

If you have defined record types for Leads in your org, you'll be able to access the Lead.RecordTypeId field.  To reliably translate that ID into the name of a record type, I would add the following property and method to the LeadUtil class:

 

private static final Map<String, Schema.RecordTypeInfo> recordTypeInfosByID =
            Schema.SObjectType.Contract.getRecordTypeInfosByID();

public static String getRecordTypeName(Id id) {
	return recordTypeInfosByID.get(id).getName();
}	// public static String getRecordTypeName(Id)

 

I would check out the "sObject Describe Result Methods" article in the Apex Developer's Guide for more info.

mayank mishra 39mayank mishra 39 
Hi Everyone,
I am getting issue while doing this LWC challenge - 
Use Lightning Data Service to Work with Data

ErrorWe can’t find an event handler named 'handleSuccess'.

Code -
contactCreator.Js
import { LightningElement,api,track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
//import CONTACT_OBJECT from '@salesforce/schema/Contact';
//import FIRSTNAME_FIELD from '@salesforce/schema/Contact.FirstName';
//import LASTNAME_FIELD from '@salesforce/schema/Contact.LastName';
//import EMAIL_FIELD from '@salesforce/schema/Contact.Email';


export default class ContactCreator extends LightningElement {
    @api recordId;
    @api objectApiName;
    @track fields = ['FirstName', 'LastName', 'Email'];

    handleSuccess(event){
        
        const toastEvent = new ShowToastEvent({
            title: "Contact created",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(toastEvent);
    }

}
contactCreator.html
<template>
    <lightning-card>
        <lightning-record-form
            object-api-name={objectApiName}
            fields={fields}
            record-id={recordId} 
            onsuccess={handleSuccess}>
        </lightning-record-form>
    </lightning-card>
</template>

Please help me what i am doing wrong here as i have declared handleSuccess event in the JS .

Thanks,
Best Answer chosen by mayank mishra 39
David Zhu 🔥David Zhu 🔥
You may need to change line 7 in html to :
onsuccess={handleSuccess}
sandeep sankhlasandeep sankhla 
I am facing the below issue while fetching the layout for account using SOAP tool. Kindly let me know how to solve this error. I have succesfully login via SOAP tool got the session id but while describing the layout I am getting the below error:

 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
   <soapenv:Header>
     
      <urn:SessionHeader>
         <urn:sessionId>Gau7XKaiaOertNGQf6UAkJiLTzNWDaW9TjrL6vq56kHRXC4yQpRj8_LLq3DZih2</urn:sessionId>
      </urn:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <urn:describeLayout>
         <urn:sObjectType>Account</urn:sObjectType>
         <urn:layoutName>Account Layout</urn:layoutName>
         </urn:describeLayout>
   </soapenv:Body>
</soapenv:Envelope>
*************************************************************************
Error:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sf="urn:fault.enterprise.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>UNKNOWN_EXCEPTION</faultcode>
         <faultstring>UNKNOWN_EXCEPTION: Destination URL not reset. The URL returned from login must be set in the SforceService</faultstring>
         <detail>
            <sf:UnexpectedErrorFault xsi:type="sf:UnexpectedErrorFault">
               <sf:exceptionCode>UNKNOWN_EXCEPTION</sf:exceptionCode>
               <sf:exceptionMessage>Destination URL not reset. The URL returned from login must be set in the SforceService</sf:exceptionMessage>
            </sf:UnexpectedErrorFault>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

Please reply in case you have solution .
Best Answer chosen by sandeep sankhla
James LoghryJames Loghry
In addition to the sessionId in your login response, you'll also need the "serverUrl" element.  Take the serverUrl and plug it into the endpoint for your describeLayout request, and you should be all set.
Samuel_NaylorSamuel_Naylor 

Hello!

It appears that all of my fields are correct, yet I cannot get past this challenge due to the error that I keep getting, in the subject line.  Is anyone able to see where I am mistaken?  Thanks in advance, for anyone's kind assistance!

Error Message:  "Could not find the 'Camping_Item__c' custom object with the correct fields."
Link to Exercise:  https://trailhead.salesforce.com/lex_dev_lc_basics/lex_dev_lc_basics_prereqs
Screen Shot:
User-added image


 

Best Answer chosen by Samuel_Naylor
Akhil AnilAkhil Anil
Hi Samuel,

FLS means field level security settings of the field. You need to go to the appropriate profile and check whether the field has appropriate access levels in the FLS. To check this follow the below path

Go to Setup > Profiles > Edit the appropriate profile and check the field level settings of your object.

Hope that helps !
James Kacerguis 5James Kacerguis 5 
Hello All,
I'm extremely new to lightning components and trying to replace some of our custom javascript buttons with lightning compatible options.  One button takes ownership of a lead.  I found a post that does something similar for cases and tried to modify it for my purpose: https://learnownlightning.blogspot.com/2018/01/change-owner-update-record-using.html

It seems to be doing the record update based on apex code, but it launches a quickaction screen with a cancel button that doens't go away.  I've seen it posted that you can use 
$A.get("e.force:closeQuickAction").fire();
It is not working for me.  I'm not sure if I'm not puting that code in the right place but I'm hoping someone can help me figure out a way to click the quick action button, have the lead change ownership, and that's it.

Here is my code so far:
Component:
<aura:component implements="force:lightningQuickAction,force:hasRecordId" controller="LightningComponent_MoveToMarketing" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>    
</aura:component>
Controller:
({
 doInit : function(component, event, helper) {
        var leadId = component.get("v.recordId");
        var action = component.get("c.changeOwnerMethod");
        action.setParams({
            leadId : leadId
        });
        action.setCallback(this, function(response) {
            if(response.getState() === "SUCCESS") {
                console.log("Lead Owner Changed To Current login User");
             var rec = response.getReturnValue();
             console.log(rec.OwnerId);
            }
        });
        $A.enqueueAction(action);
$A.get("e.force:closeQuickAction").fire();
        $A.get('e.force:refreshView').fire();
 }
})

Apex Class:
public class LightningComponent_MoveToMarketing {

    @AuraEnabled
    public static Lead changeOwnerMethod(Id leadId) {
        if(leadId != null) {
            Lead l = [SELECT OwnerId FROM Lead WHERE Id = :leadId];
         l.OwnerId = UserInfo.getUserId();
//update case Ownerid with loggedin userid.
            update l;
            return l;
        }
        return null;
    }

}

Any ideas?
 
Best Answer chosen by James Kacerguis 5
lnallurilnalluri
Move 
$A.get("e.force:closeQuickAction").fire();
        $A.get('e.force:refreshView').fire();

inside the callback function. It should be good then.

Your controller should be like this.
({
 doInit : function(component, event, helper) {
        var leadId = component.get("v.recordId");
        var action = component.get("c.changeOwnerMethod");
        action.setParams({
            leadId : leadId
        });
        action.setCallback(this, function(response) {
            if(response.getState() === "SUCCESS") {
                console.log("Lead Owner Changed To Current login User");
             var rec = response.getReturnValue();
             console.log('->'+rec.OwnerId);
                $A.get("e.force:closeQuickAction").fire();
        $A.get('e.force:refreshView').fire();
            }
        });
        $A.enqueueAction(action);

 }
})

Please mark it solved if this is working for you.

Thanks.​​​​​​​
Puneet KhoslaPuneet Khosla 
I am getting this error when trying to do the "Lightning Experience Rollout Specialist"

The AccountTab Visualforce page does not include one or both of the following: the apex:slds tag in the page, or the slds-table value in the table.


My code is as follows:
 
<apex:page standardStylesheets="false" standardController="Account" recordSetVar="accounts" tabStyle="account" applyHtmlTag="false" applyBodyTag="false" showHeader="false">
   <head>
       <apex:slds />
    </head> 
	<body>
    <div class="slds-scope">     
        <table class="slds-table">
  			<thead>
    			<tr class="slds-text-title_caps">
      				<th scope="col">
        				<div class="slds-truncate" title="{!$ObjectType.Account.Fields.Name.Label}">{!$ObjectType.Account.Fields.Name.Label}</div>
      				</th>
    			</tr>
  			</thead>
  			<tbody>
    			<apex:repeat value="{!accounts}" var="a">
                <tr>
                  <td data-label="Account Name">
                    <div class="slds-truncate" ><apex:outputLink value="{!URLFOR($Action.Account.View, a.id)}">{!a.name}</apex:outputLink></div>
                  </td>
      
    			</tr>
                </apex:repeat>
            </tbody>
        </table>
     <!--   
     <div class="slds-scope">
        <apex:pageBlock >
            <apex:pageBlockTable value="{!accounts}" var="a" styleClass="slds">
                <apex:column headerValue="{!$ObjectType.Account.Fields.Name.Label}">
                    <apex:outputLink value="{!URLFOR($Action.Account.View, a.id)}">{!a.name}</apex:outputLink>
                </apex:column>
            </apex:pageBlockTable>
        </apex:pageBlock>-->
    </div>
        </body>
</apex:page>

 
Best Answer chosen by Puneet Khosla
Puneet KhoslaPuneet Khosla
Looks like I figured out.

styleClass="slds-table" needs to be added to pageBlockTable
vijayprakashpjvijayprakashpj 
Hello,

I have created an inbound email handler that processes XML email body. The email will be triggered by a third party application directly to Salesforce's email handler id. These emails are not being processed by Salesforce. However, Salesforce processes the email sent from my email account.

Also, I have my email domain and the third party app's email domain names in the Accept Email From setting.

I have set the failure scenario configuration as shown below:
Email Services Failure Configuration


I need help in finding out if the emails are actually being received by Salesforce.

-Vijay
Best Answer chosen by vijayprakashpj
vijayprakashpjvijayprakashpj
I have figured out the problem and fixed it.

There are two 'Accept Email From' fields, one in the Email Services page and the other one in the Email Address configuration page. I had put my name in the second one which was why Salesforce was not accepting any emails from other email ids. My bad!