0

How to show list of contacts in a child component based on the Parent component Account Id, I have a Parent component which shows the list of Accounts and I would like to get all the related contacts of the Account to be displayed in a child component, when I change the Account name in the list. I have used the lightning:select tag and the aura:iteration to get the respective Account Id, when the item is selected from the parent component list. How to pass this Account Id within the iteration to the child component to show the related contacts.

//Parent Component
<aura:component controller="AccountListController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >

<aura:attribute name="accounts" type="Account[]" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

<aura:attribute name="parentAttr" type="String" default="parent attribute"/>

<lightning:select label="Your Accounts" name="a_opt" aura:id="a_opt" onchange="{!c.change}">
    <aura:iteration items="{!v.accounts}" var="account">
        <option value="{!account.Id}"> {!account.Name} </option>
        <!-- <c:ContactsList childAttr="{#v.parentAttr}" /> -->
    </aura:iteration>
</lightning:select>

// Apex Controller
global class AccountListController {
  @AuraEnabled 
  global static Account[] getAccountList() {
    return [SELECT Name FROM Account LIMIT 10];
  }
}


// Js Controller
({
doInit: function(component, event, helper) {
    // Request from server
    var action = component.get("c.getAccountList");
    action.setCallback(this, function(result){
        var accounts = result.getReturnValue();
        console.log(accounts);
        component.set("v.accounts", accounts);

    $A.enqueueAction(action);
},

change: function(cmp,event,hlpr){

    var AccId = cmp.find("a_opt").get("v.value");
    cmp.set("v.parentAttr", AccId);

}
})
1
  • Use two-way data binding <c:ContactsList childAttr="{!v.parentAttr}" /> and in the child component add change handler for childAttr and in the change handler method fetch the data for the changed childAttr value. Commented Nov 28, 2017 at 4:24

1 Answer 1

1

There are multiple methods by which you can bind parent attribute to child object

  1. You can query Contact records along with Account and pass them into your child.
  2. You can pass accountId to child object and listen for change event.

I am showing you second method here

ContactList.cmp

<aura:component controller="AccountListController">
    <aura:attribute name="Contacts" type="Contact[]" />
    <aura:attribute name="accountId" type="String" />
    <aura:handler name="change" value="{!v.accountId}" action="{!c.itemsChange}"/>
    <aura:if isTrue="{!!empty(v.Contacts)}">
        <lightning:select label="Your Contacts" name="a_opt">
            <aura:iteration items="{!v.Contacts}" var="Contact">
                <option value="{!Contact.Id}"> {!Contact.Name} </option>
                <!-- <c:ContactsList childAttr="{#v.parentAttr}" /> -->
            </aura:iteration>
        </lightning:select>
        <aura:set attribute="else">
            No Contact Found
        </aura:set>
    </aura:if>
</aura:component>

Here you can notice that we are using aura:handler for accountId chnage from parent component. We will pass this to apex method to get all contacts

ContactList.js

({
    itemsChange : function (component, event, helper) {
        // handle value change
        var action = component.get("c.getContactList");
         action.setParams({
            accountId : event.getParam("value")
        });     
        action.setCallback(this, function(result){

            var accounts = result.getReturnValue();

            console.log(accounts);
            component.set("v.Contacts", accounts);
        });

        $A.enqueueAction(action);


    }
})

Your parent component can be updated as follows

<aura:component controller="AccountListController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >

    <aura:attribute name="accounts" type="Account[]" />

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

    <aura:attribute name="parentAttr" type="String" default=""/>

    <lightning:select label="Your Accounts" name="a_opt" aura:id="a_opt" onchange="{!c.change}">
        <aura:iteration items="{!v.accounts}" var="account">
            <option value="{!account.Id}"> {!account.Name} </option>
            <!-- <c:ContactsList childAttr="{#v.parentAttr}" /> -->
        </aura:iteration>
    </lightning:select>

    <!-- check for blank parentId and hide contact list -->
    <aura:if isTrue="{!!empty(v.parentAttr)}">
        <c:ContactList accountId="{!v.parentAttr}"/>
    </aura:if>

</aura:component>

We need to add one method in apex to get contact as shown below

// Apex Controller
global class AccountListController {
    @AuraEnabled 
    global static Account[] getAccountList() {
        return [SELECT Name FROM Account LIMIT 10];
    }

    @AuraEnabled 
    global static Contact[] getContactList(String accountId) {
        return [SELECT id,Name FROM Contact where accountId=:accountId LIMIT 10];
    }

}

Not the answer you're looking for? Browse other questions tagged .