1

Let's say we have

<template>
<template if:false={isLoading}>
    <div class="cxd-history__container" onscroll={handleScroll}>
            <template for:each={historyList} for:item="historyItem">
                <div key={historyItem.emailName}>
                    <c-email-card payload={historyItem}></c-email-card>
                </div>
            </template>            
    </div>
</template>
<template if:true={isLoading}>
    <div class="cxd-loading-spinner">
        <lightning-spinner alternative-text="Loading" size="medium"></lightning-spinner>
      </div>
</template>

and controller is

export default class EmailHistory extends LightningElement {
@api recordId;
historyList = [];
isLoading = false;
page = 0;
connectedCallback() {
  this.loadMore();
}
handleScroll = (e) => {
    const target = e.target;
    if(target.scrollHeight - target.scrollTop <= target.clientHeight) {
        this.loadMore();
    }
}
loadMore = () => {
    if(this.isLoading) return;
    this.isLoading = true;
    this.page++;
    getNext({page: this.page, pageSize: PAGE_SIZE, accountId: this.recordId})
        .then(data => {
            this.historyList = [...this.historyList, ...JSON.parse(data)];
            this.isLoading = false;
        })
        .catch(error => {
            console.log('error',(error));
        })
        .finally(() => {
            this.isLoading = false;
        });
}

every time i scrolled it down i've got expected results but from the early beginning. is that some workaround to simulate kinda 'loadMore` when it comes to lightning-datatatable? (it isn't possible to use datatable in my case)

1 Answer 1

0

Your recordId is likely not populated when connectedCallback is called. I know they say it should be, but I've found that it's often null at this point.

Use a getter/setter to handle this:

@api
get recordId() {
  return this._recordId;
}
  
set recordId(value) {
  this._recordId = value;
  this.getFirstPage();
}

You COULD use a wired function to handle this to call your data function, but it's easier to just call your data getter in the setter, as above.

getFirstPage just sets up the required params:

getFirstPage = () => {
    if(this.isLoading) return;
    this.isLoading = true;
    this.callGetNext(this.page,PAGE_SIZE,this.recordId);
}

callGetNext => (page, pageSize, accountId){
  getNext({page: page, pageSize: pageSize, accountId: accountId})
    .then(data => {
      this.historyList = [...this.historyList, ...JSON.parse(data)];
      this.isLoading = false;
    })
    .catch(error => {
      console.log('error',(error));
    });
}

loadMore is similar to get first page:

loadMore = () => {
    if(this.isLoading) return;
    this.isLoading = true;
    this.page++;
    this.callGetNext(this.page,PAGE_SIZE,this.recordId);
}

You would also entirely remove the connectectedCallback. I think that'll do it.

1
  • I beleive that for:each matters so temolate is getting re-rendered each time onscroll got fired. Can you gutys suggest some workaround?
    – pincet
    Oct 23, 2023 at 6:29

You must log in to answer this question.

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