Ans:-
Custom Implementation
Here is approach to get read the large list with paging implementation.
Consider we have a SharePoint list named “LargeList” with below schema:
| Field Name | Type |
| Title | Single line of text |
| Description | Multiple lines of text |
| Category | Single line of text |
| Quantity | Number |
The model to represent above list item will be as below:
export interface ILargeListItem {
Title: string;
Description: string;
Category: string;
Quantity: number;
}
Let us define our approach to handle large list:
- We will define the page size as 5000 for example (maximum threshold limit). Please note, SharePoint internally fetches the items in the batch of 100 items.
- The number of requests we will have to read entire large list will be: Number of list items / page size.
- We will make asynchronous requests to read the list items in batch.
- Wait for all asynchronous requests to finish
Implement a genetic method getPageListItems which returns items with paging, starting with index passed as an argument.
$skiptoken=Paged=TRUE%26p_ID=` + (index * Constants.Page_Size + 1)
The getPageListItems method implementation will look as follows:
private getPageListItems(listTitle: string, index: number): Promise<ILargeListItem[]> {
return new Promise<ILargeListItem[]>((resolve, reject): void => {
let requestUrl = this.context.pageContext.web.absoluteUrl
+ `/_api/web/Lists/GetByTitle('` + listTitle + `')/items`
+ `?$skiptoken=Paged=TRUE%26p_ID=` + (index * Constants.Page_Size + 1)
+ `&$top=` + Constants.Page_Size
+ `&$select=ID,Title,Description,Category,Quantity`;
this.context.spHttpClient.get(requestUrl, SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
response.json().then((responseJSON: any) => {
resolve(responseJSON.value);
});
});
});
}
Implement a method to get the latest item id. This will be our maximum limit to read the items.
public getLatestItemId(listTitle: string): Promise<number> {
return new Promise<number>((resolve: (itemId: number) => void, reject: (error: any) => void): void => {
sp.web.lists.getByTitle(listTitle)
.items.orderBy('Id', false).top(1).select('Id').get()
.then((items: { Id: number }[]): void => {
if (items.length === 0) {
resolve(-1);
}
else {
resolve(items[0].Id);
}
}, (error: any): void => {
reject(error);
});
});
}
The next step is to implement method the main method to make asynchronous requests to read the list items in batch.
public async getLargeListItems(listTitle: string): Promise<ILargeListItem[]> {
var largeListItems: ILargeListItem[] = [];
return new Promise<ILargeListItem[]>(async (resolve, reject) => {
// Array to hold async calls
const asyncFunctions = [];
this.getLatestItemId(listTitle).then(async (itemCount: number) => {
for (let i = 0; i < Math.ceil(itemCount / Constants.Page_Size); i++) {
// Make multiple async calls
let resolvePagedListItems = () => {
return new Promise(async (resolve) => {
let pagedItems:ILargeListItem[] = await this.getPageListItems(listTitle, i);
resolve(pagedItems);
})
};
asyncFunctions.push(resolvePagedListItems());
}
// Wait for all async calls to finish
const results: any = await Promise.all(asyncFunctions);
for (let i = 0; i < results.length; i++) {
largeListItems = largeListItems.concat(results[i]);
}
resolve(largeListItems);
});
});
}