lightning:tree Select and add child node dynamically

A lightning:tree component displays the visualization of a structural hierarchy, such as a sitemap for a website or a role hierarchy in an organization. in this example, I will show how to add the child node to the selected node. in this example, the user selects the account and add the child contacts to that account as shown below as shown below. The below image shows the tree before the user add the contacts 

The below image shows the tree after the user adds the contacts. when the user clicks on add contact that will add the contact”test email ” to the selected account.

Apex Class

public class TreeControllerUpdate {
    @AuraEnabled
    public static String getTreeData(){
        List<Account> accs = [Select Id , Name,Rating,Type,(Select Id , Name,FirstName ,LastName,Email from Contacts) from Account];
        List<AccountWrapper> aooo = new List<AccountWrapper>();
        for(Account a : accs){
            AccountWrapper aWraper = new AccountWrapper() ; 
            aWraper.name =a.Id ;
            aWraper.label =a.Name ;
            //aWraper.metatext = a.Name+'-'+a.Type+'-'+a.Rating ;
            aWraper.expanded =false ;
            List<Items> co = new List<Items>();
            for(Contact c : a.Contacts){
                Items conWrapp = new Items();
                conWrapp.name =c.Id ;
                // conWrapp.metatext =c.FirstName+'-'+c.LastName+'-'+c.Email;
                conWrapp.label =c.Name ;
                conWrapp.expanded =false ;
                co.add(conWrapp);
            }
            aWraper.items = co;
            aooo.add(aWraper);
            
        }
        return JSON.serializePretty(aooo) ;
    } 
    public Class AccountWrapper{
        @AuraEnabled
        public String name {get;set;}
        @AuraEnabled
        public String label {get;set;}
        @AuraEnabled
        public Boolean expanded {get;set;}
        @AuraEnabled
        public List<Items> items {get;set;}
        
    }
    public Class Items{
        @AuraEnabled
        public String name {get;set;}
        @AuraEnabled
        public String label {get;set;}
        @AuraEnabled
        public Boolean expanded {get;set;}
        @AuraEnabled
        public List<Items> items {get;set;}
    }
    @AuraEnabled
    public static Contact saveContact(String accId){
        Contact con = new Contact(LastName='Test' , FirstName='Email', Email='Test@gmail.com' ,Phone ='12121212' ,AccountId =accId) ; 
        insert con ; 
        return con ;
    }
    
}

 

Lightning Component 

<aura:component controller="TreeControllerUpdate" implements="flexipage:availableForAllPageTypes,force:appHostable,flexipage:availableForRecordHome,force:hasRecordId,force:hasSObjectName">
    <aura:attribute name="items" type="Object"/>
    <aura:attribute name="selectedId" type="String"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <lightning:button iconName="utility:add" onclick="{! c.handleClick }" variant="brand" label="Add Contact" value="0"/>
    <lightning:tree items="{! v.items }" header="Account - Contact - Opportunity" onselect="{!c.handleSelect}"/>
</aura:component>

 

({
    doInit: function (cmp, event, helper) {
        var action = cmp.get("c.getTreeData");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                cmp.set('v.items', JSON.parse(response.getReturnValue()));
            }
            
        });
        $A.enqueueAction(action);
    },
    handleSelect: function (cmp, event, helper) {
        var id = event.getParam('name');
        cmp.set("v.selectedId" ,id);
    },
    handleClick:  function(cmp, event) {
        var action = cmp.get("c.saveContact");
        action.setParams({accId:cmp.get("v.selectedId")});
        action.setCallback(this, function(response) {
            var nodeToAdd = cmp.get("v.selectedId");
            var state = response.getState();
            if (state === "SUCCESS") {
                var obj= response.getReturnValue() ; 
                var item = cmp.get('v.items');
                var newItem = {
                    label: obj.LastName+ ' ' +obj.FirstName,
                    name: obj.Id,
                    expanded: true,
                    disabled: false,
                    items: []
                };
                item.forEach(function(entry) {
                    if(entry.name==nodeToAdd){
                        entry.items.push(newItem);
                    }
                });
                cmp.set('v.items' , item);
            }
            $A.get('e.force:refreshView').fire();
        });
        $A.enqueueAction(action);
        
        
    }
    
})