+ Start a Discussion
David Webb 26David Webb 26 

Lightning datatable refresh

Is there a way to refresh the data in a lightning datatable after making an update via an apex class?
Best Answer chosen by David Webb 26
David Webb 26David Webb 26
Thanks, Khan.  Actually I was looking for a lightning web component solution.  I did find one, though!

Here's the html for my component which is just a lightning-datatable that lists out opportunties.  What I was trying to accomplish was select one or more rows and then update each selected record with an apex method.  Following the update, I wanted to refresh the datatable.  This code does that.

HTML
<template>
    <lightning-card title="Update Opportunities">
        <p>
            <lightning-button label="Close Opportunities" onclick={getSelectedName}></lightning-button>
        </p>
        <lightning-datatable data={data} columns={columns} key-field="Id" selected-rows={selectedRows}>
        </lightning-datatable>
    </lightning-card>
</template>

JS
import { LightningElement,track, wire} from 'lwc';
import getAllOpps from '@salesforce/apex/GetAllOpportunities.getAllOpps';
import updateOpportunityNames from '@salesforce/apex/UpdateOpportunities.updateOpportunityNames';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class DatatableEx12 extends LightningElement {
    @track columns = [{
            label: 'Opportunity name',
            fieldName: 'Name',
            type: 'text',
            sortable: true
        },
        {
            label: 'Stage Name',
            fieldName: 'StageName',
            type: 'text',
            sortable: true
        },
        {
            label: 'Close date',
            fieldName: 'CloseDate',
            type: 'date',
            sortable: true
        }

    ];

    wiredDataResult;
    @track error;
    @track data ;
    @wire(getAllOpps)
    wiredOpps(result) {

        this.wiredDataResult = result;
        if (result.data) {
            this.data = result.data;
         
        }
    }

   

    getSelectedName() {
        const selectedRows = this.template.querySelector('lightning-datatable').getSelectedRows();
        const selectedIds = [];
        
        
        // Display that fieldName of the selected rows
        for (let i = 0; i < selectedRows.length; i++){
            selectedIds.push(selectedRows[i].Id);
            console.log("You selected: " + selectedRows[i].Id);
        }

        updateOpportunityNames({ids: selectedIds}).then(result => {
            console.log("Opps updated!" + result)
             // Display fresh data in the datatable
             this.selectedRows = [];
             return refreshApex(this.wiredDataResult);
        }).catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error creating record',
                    message: error.message,
                    variant: 'error'
                })
            );
        });
    }
}

GetAllOpportunities.cls
public with sharing class GetAllOpportunities {
   @AuraEnabled(cacheable=true)
    public static List<Opportunity> getAllOpps() {
        return [SELECT Id, Name ,StageName, CloseDate ,Type ,Probability,Account.Name from Opportunity limit 10];
    }
}

UpdateOpportunities.cls
public with sharing class UpdateOpportunities {
    @AuraEnabled()
    public static void updateOpportunityNames(String[] ids) {

        List<Opportunity> opportunitiesToUpdate = new List<Opportunity>();
        List<Opportunity> selectedOpportunities = [SELECT Id, Name FROM Opportunity WHERE Id in :ids];

        Integer i = 0;
        for (Opportunity opportunity : selectedOpportunities){
                          
            opportunity.StageName = 'Closed';
            opportunitiesToUpdate.add(opportunity);
            i++;
    	}
        

        update opportunitiesToUpdate;
    }
}

 

All Answers

Khan AnasKhan Anas (Salesforce Developers) 
Hi David,

Greetings to you!

You can use force:refreshView to request a page refresh. Try like this:
 
clientMethod : function(component,event,helper) {
        var action = component.get("c.serverMethod");   //calling server-side method
        action.setParams({
        "serverParameter":clientParameter
    });
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS'){
                $A.get('e.force:refreshView').fire();
            }
            ...
            ...
            ...
        )};
        $A.enqueueAction(action);
},

/*page refresh after data save*/
    
    isRefreshed: function(component, event, helper) {
        location.reload();
    },

And don't forget to add below handler in your component:
<aura:handler event="force:refreshView" action="{!c.isRefreshed}" />

Or you can call init method in handler action: <aura:handler event="force:refreshView" action="{!c.doInit}" />

Please try the below code, I have tested in my org and it is working fine. Kindly modify the code as per your requirement.

Apex:
public class UpdateDataTable_TaskSvrController {
    
    @AuraEnabled
    public static List<Account> details(){
        List<Account> lst = [SELECT Name, Phone, Rating, NumberOfEmployees FROM Account LIMIT 10];
        return lst;
    }

    @AuraEnabled
    public static List<Account> updateDetails(List<Account> lstForm) {
        update lstForm;
        return lstForm;
    }
}

Component:
<aura:component controller="UpdateDataTable_TaskSvrController"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
	
    <aura:attribute name="PageHeading" type="String" default="Update Using Data Table"/>
    <aura:attribute name="mydata" type="Account"/>
    <aura:attribute name="mycolumns" type="List"/>
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:handler event="force:refreshView" action="{!c.doInit}" />
    
    <div class="slds-m-top--xx-large">
    	<div class="slds-page-header">
    		<div class="slds-align--absolute-center">
        		<div class="slds-text-heading--large">       
    				{!v.PageHeading}
                </div>
        	</div>
    	</div>
    </div>
    <br/> <br/>
    
    <div id="dt">
        <lightning:datatable aura:id="iliDataTable"
                             data="{! v.mydata }"  
                             columns="{! v.mycolumns }" 
                             keyField="Id" 
                             hideCheckboxColumn="false" 
                             onsave="{!c.saveTable}" />
    </div>
</aura:component>

Controller:
({
    doInit : function(component, event, helper) {
        component.set('v.mycolumns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text', editable: true, initialWidth: 750},
            {label: 'Phone', fieldName: 'Phone', type: 'phone', editable: true},
            {label: 'Rating', fieldName: 'Rating', type: 'text', editable: true},
            {label: 'Number Of Employees', fieldName: 'NumberOfEmployees', type: 'number', editable: true}
        ]);
        
        var action = component.get("c.details");
        action.setCallback(this, function(response) {
            var state = response.getState();
            
            if (state === "SUCCESS") {
                var res = response.getReturnValue();
                component.set("v.mydata", res);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } 
                else {
                    console.log(response.getReturnValue());
                }
            }
        });
        $A.enqueueAction(action);
    },
    
    saveTable : function(component, event, helper){     
        //var data = component.get("v.mydata");
        var draftValues = event.getParam('draftValues');
        var action = component.get("c.updateDetails");
        action.setParams({lstForm  : draftValues});
        action.setCallback(this, function(response) {
            var state = response.getState();
            
            if (state === "SUCCESS") {
                var res = response.getReturnValue();
                $A.get('e.force:refreshView').fire();
                alert('Updated Successfully...');
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                    errors[0].message);
                    }
                } 
                else {
                    console.log(response.getReturnValue());
                }
            }
        });
        $A.enqueueAction(action);
    }
})

CSS:
.THIS {

}

.THIS.slds-size--3-of-8 {
    
    margin-left: 430px;
}

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
David Webb 26David Webb 26
Thanks, Khan.  Actually I was looking for a lightning web component solution.  I did find one, though!

Here's the html for my component which is just a lightning-datatable that lists out opportunties.  What I was trying to accomplish was select one or more rows and then update each selected record with an apex method.  Following the update, I wanted to refresh the datatable.  This code does that.

HTML
<template>
    <lightning-card title="Update Opportunities">
        <p>
            <lightning-button label="Close Opportunities" onclick={getSelectedName}></lightning-button>
        </p>
        <lightning-datatable data={data} columns={columns} key-field="Id" selected-rows={selectedRows}>
        </lightning-datatable>
    </lightning-card>
</template>

JS
import { LightningElement,track, wire} from 'lwc';
import getAllOpps from '@salesforce/apex/GetAllOpportunities.getAllOpps';
import updateOpportunityNames from '@salesforce/apex/UpdateOpportunities.updateOpportunityNames';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class DatatableEx12 extends LightningElement {
    @track columns = [{
            label: 'Opportunity name',
            fieldName: 'Name',
            type: 'text',
            sortable: true
        },
        {
            label: 'Stage Name',
            fieldName: 'StageName',
            type: 'text',
            sortable: true
        },
        {
            label: 'Close date',
            fieldName: 'CloseDate',
            type: 'date',
            sortable: true
        }

    ];

    wiredDataResult;
    @track error;
    @track data ;
    @wire(getAllOpps)
    wiredOpps(result) {

        this.wiredDataResult = result;
        if (result.data) {
            this.data = result.data;
         
        }
    }

   

    getSelectedName() {
        const selectedRows = this.template.querySelector('lightning-datatable').getSelectedRows();
        const selectedIds = [];
        
        
        // Display that fieldName of the selected rows
        for (let i = 0; i < selectedRows.length; i++){
            selectedIds.push(selectedRows[i].Id);
            console.log("You selected: " + selectedRows[i].Id);
        }

        updateOpportunityNames({ids: selectedIds}).then(result => {
            console.log("Opps updated!" + result)
             // Display fresh data in the datatable
             this.selectedRows = [];
             return refreshApex(this.wiredDataResult);
        }).catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error creating record',
                    message: error.message,
                    variant: 'error'
                })
            );
        });
    }
}

GetAllOpportunities.cls
public with sharing class GetAllOpportunities {
   @AuraEnabled(cacheable=true)
    public static List<Opportunity> getAllOpps() {
        return [SELECT Id, Name ,StageName, CloseDate ,Type ,Probability,Account.Name from Opportunity limit 10];
    }
}

UpdateOpportunities.cls
public with sharing class UpdateOpportunities {
    @AuraEnabled()
    public static void updateOpportunityNames(String[] ids) {

        List<Opportunity> opportunitiesToUpdate = new List<Opportunity>();
        List<Opportunity> selectedOpportunities = [SELECT Id, Name FROM Opportunity WHERE Id in :ids];

        Integer i = 0;
        for (Opportunity opportunity : selectedOpportunities){
                          
            opportunity.StageName = 'Closed';
            opportunitiesToUpdate.add(opportunity);
            i++;
    	}
        

        update opportunitiesToUpdate;
    }
}

 
This was selected as the best answer
Ajay K DubediAjay K Dubedi
Hi David,

After geting response from apex controller you have to call doInit method again inside that method in which you call apex controller.

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
anajli sharmaanajli sharma
ftyfy gyugyuftyfy gyugyu
Is this good idea to use this script in content based website that hosted on WordPress? I want to use for my site of musical hunter (https://musicalhunter.com/). Kindly Guide me regarding this.
Ryan Khan 1Ryan Khan 1
You can also check Showbox APK (https://apksclub.com/showbox-apk/) for free unlimited movies.