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);
});
});
}