0

I have a "aura: component" with "lightning: datatable" and have a "doInit" method in js controller. My spreadsheet page worked well and reflected my data. But then I decided to split my "doInit" method into parts so as not to duplicate the code in other places and use these methods. And now I have a problem, my code doesn't work. I know for sure that "doInit" works and pulls information from the database. What could be the problem? enter image description here

<aura:component controller="ContactsManagerController"  implements="force:appHostable">
...
    <aura:attribute name="dataList" type="List"/>
    <aura:attribute name="columns" type="List"/>
    <aura:attribute name="paginationList" type="List"/>
    <aura:handler name="doInit" value="{! this }" action="{! c.doInit }"/>
    <lightning:datatable    keyField="id"
                            columns="{!v.columns }"
                            data="{!v.paginationList}"
                            hideCheckboxColumn="true"
                            defaultSortDirection="{!v.defaultSortDirection}"
                            sortedDirection="{!v.sortDirection}"
                            sortedBy="{!v.sortedBy}"
                            onsort="{!c.handleSort}"
                            onrowaction="{!c.handleRowAction}"
                            selectedRows="false"
                            showRowNumberColumn="false"/>
...
</aura:component>

//js

({
    doInit : function (component, event, helper) {
          component.set('v.columns', [
               { label: 'Name', fieldName: 'Name', sortable: true  },
               { label: 'Email', fieldName: 'Email', type: 'email', sortable: true  },
               { label: 'Contact Level', fieldName: 'Contact_Level__c', sortable: true  },
               { label: 'Account', fieldName: 'AccountName', type: 'text', sortable: true  },
               { label: 'Owner', fieldName: 'OwnerName', type: 'text', sortable: true  },
               { label: 'Created By', fieldName: 'CreatedByName', type: 'text', sortable: true  },
               { label: 'Created Date', fieldName: 'CreatedDate', type: 'date', sortable: true  },
               { label: 'Action', type: 'button',
                typeAttributes: { label: 'Del', name: "delete", variant: 'destructive', onclick: 
               '{!c.deleteTableRows}' },
               },
               ]);
          component.getDataFromDB();
          component.calculateAmountPage();
          component.getDisplayDataPagination();
    },
    
    getDataFromDB : function(component, event, helper){
      // show spinner message
      component.find("Id_spinner").set("v.class" , 'slds-hide');  
        var action;
          var searchKeyword = component.get("v.searchKeyword");
            if(searchKeyword != null){
                   action = component.get("c.fetchContact");
                   action.setParams({'searchKeyword': component.get("v.searchKeyword")});
               } else {
                   action = component.get('c.getListContacts');
               }
        action.setCallback(this, function(response){
        //hide spinner when response coming from server
        component.find("Id_spinner").set("v.class" , 'slds-hide');
            var state = response.getState();
               if (state === "SUCCESS") {
                   var rows = response.getReturnValue();
                   for (var i = 0; i < rows.length; i++) {
                       var row = rows[i];
                       if (row.Account) {
                           row.AccountName = row.Account.Name;
                       };
                       if(row.Owner) {
                           row.OwnerName = row.Owner.Name;
                       };
                       if(row.CreatedBy) {
                           row.CreatedByName = row.CreatedBy.Name;
                       };
                   }
                   component.set("v.dataList", rows);
               }
           });
           $A.enqueueAction(action);
    },
    
    getDisplayDataPagination : function(component, event){
        var currentPage = component.get("v.currentPage");
        var dataList = component.get("v.dataList");
        var paginationList = [];
        var pageSize = component.get("v.pageSize");
            for(var i = (currentPage - 1) * pageSize; i < currentPage * pageSize; i++){
                 paginationList.push(dataList[i]);
            }
        component.set("v.paginationList", paginationList);
    },
                
    calculateAmountPage : function(component, event, helper) {
         component.set("v.totalSize", component.get("v.dataList").length);
         var totalSize = component.get("v.totalSize");
         var pageSize = component.get("v.pageSize");
         var amountPage;
                if(totalSize % pageSize == 0)
                {
                  amountPage = totalSize / pageSize;
                  }
              else
                    {
              amountPage = (Math.trunc(totalSize / pageSize) + 1);
              }
              if (amountPage == 0){
                  amountPage = 1; 
              }
         component.set("v.endPage", amountPage);
    },
})

//apxc

@AuraEnabled(cacheable=true)
public static List<Contact> getListContacts() {
    List<Contact> listContacts = [SELECT  Name, Email, Contact_Level__c, Account.Name, Owner.Name, 
    CreatedBy.Name, CreatedDate  FROM  Contact];
  return listContacts;
}
1
  • "This page has an error. You might just need to refresh it. Failed to initialize a component [Cannot read property 'h' of undefined] Failing descriptor: {c:ContactsManager1App}". I managed to concretize the error and I accidentally found out that it arose due to the fact that I had renamed the "init" method to "doInit" (in cmp) the previous day. When I changed the name back, everything worked. If I hadn't done this out of stupidity, I wouldn't have had to ask for help. But now I know more. Thank! Commented Mar 2, 2021 at 13:29

2 Answers 2

0

calculateAmountPage() and getDisplayDataPagination() are running synchronously after getDataFromDB() - but critically, not after the asynchronous server call enqueued in getDataFromDB() completes.

Your refactor has created a race condition between the server call and the two later methods you factored out of doInit(), a race condition that will usually result in your code seeing no returned data because server calls are slow.

Instead of calling calculateAmountPage() and getDisplayDataPagination() in doInit(), call them in the callback function inside getDataFromDB() to ensure that data is available.

1
  • @PapaChaos Thanks for the help! I understood. But in the process I got an additional error elsewhere (about which I added a comment to my question), so the code rearrangements undertaken did not give a result. Commented Mar 3, 2021 at 13:55
1

One potential source of problems is that the database call is asynchronous; your calculateAmountPage and getDisplayDataPagination functions may very well be called before the database call returns. You can try calling these from the callback function instead of sequentially in the doInit to see if that makes a difference.

0

You must log in to answer this question.

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