Enhancing SharePoint List Fetching: Additional Fields, Filters, and Pagination
Retrieving SharePoint list items is essential in many SPFx solutions. However, in real-world scenarios, you may need to:
- Include additional fields: Fetch more columns from the list beyond the default ones.
- Apply filters: Retrieve only specific items based on conditions.
- Handle pagination: Fetch large lists efficiently without hitting API limits.
Code Enhancement
The updated function allows:
✅ Specifying additional fields using $select
✅ Applying filters with $filter
✅ Handling pagination using @odata.nextLink
import { HttpClient, HttpClientResponse } from '@microsoft/sp-http';
/**
* Fetches SharePoint list items with optional fields, filters, and pagination.
*
* @param {any} context - The SharePoint context for API calls.
* @param {string} listTitle - The SharePoint list title.
* @param {string[]} additionalFields - List of extra fields to retrieve.
* @param {string} filter - OData filter string (optional).
* @returns {Promise<any[]>} - Returns a structured array of list items.
*/
export async function FetchListItemsExtended(
context: any,
listTitle: string,
additionalFields: string[] = [],
filter: string = ""
): Promise<any[]> {
try {
const siteUrl = context.pageContext.web.absoluteUrl;
const selectFields = ["Id", "Title", "Created", "Modified", ...additionalFields].join(",");
let apiUrl = `${siteUrl}/_api/web/lists/getbytitle('${listTitle}')/items?$select=${selectFields}`;
if (filter) {
apiUrl += `&$filter=${encodeURIComponent(filter)}`;
}
console.log("Fetching API URL:", apiUrl);
let allItems: any[] = [];
let nextUrl: string | null = apiUrl;
// Handle pagination by iterating through nextLink responses
while (nextUrl) {
const response: HttpClientResponse = await context.httpClient.get(nextUrl, HttpClient.configurations.v1, {
headers: {
'Accept': 'application/json;odata=nometadata',
'Content-Type': 'application/json;odata=nometadata'
}
});
console.log("Response Status:", response.status);
if (!response.ok) {
throw new Error(`Failed to fetch list items: ${response.statusText}`);
}
const data = await response.json();
console.log("Raw Data:", data);
allItems = [...allItems, ...data.value];
// Check for pagination
nextUrl = data["@odata.nextLink"] || null;
}
// Transform the list items into a structured object
const items = allItems.map((item: any) => ({
id: item.Id,
title: item.Title,
created: item.Created,
modified: item.Modified,
...additionalFields.reduce((obj, field) => ({ ...obj, [field]: item[field] || null }), {})
}));
console.log("Processed Items:", items);
return items;
} catch (error) {
console.error("Error fetching list items:", error);
return [];
}
}
Example Usage
1️⃣ Fetching Items with Additional Fields
const listItems = await FetchListItemsExtended(context, "Documents", ["Author", "Category"]);
console.log(listItems);
2️⃣ Filtering Items (e.g., only documents created in 2024)
const filter = "Created ge datetime'2024-01-01T00:00:00Z'";
const filteredItems = await FetchListItemsExtended(context, "Documents", ["Author"], filter);
console.log(filteredItems);
3️⃣ Fetching Large Lists with Pagination
The function automatically handles large lists using @odata.nextLink, ensuring that all items are retrieved efficiently.
Conclusion
This enhanced function provides:
✔️ Flexibility – Fetch any fields you need
✔️ Filtering – Retrieve only relevant data
✔️ Performance Optimization – Efficiently handle large lists
With this approach, your SPFx solutions can be more scalable and efficient.
