Home >Web Front-end >JS Tutorial >Multiple fields sorting with a time saving function for server side developer (api pagination)
Application scenarios:
Supports multiple sorting methods:
https://your-url?sort[first_name]=desc&sort[last_name]=asc
https://your-url?sort[first_name]=ascending&sort[last_name]=descending
https://your-url?sort[first_name]=1&sort[last_name]=-1
This function also supports sorting using the sortBy
and sortOrder
fields: https://your-url?sortOrder=desc&sortBy=last_name
TypeScript code:
<code class="language-typescript">type ISortOrder = "asc" | "desc" | "ascending" | "descending" | 1 | -1; export interface IPaginationFields { page?: number; limit?: number; sortBy?: string | string[]; sortOrder?: ISortOrder | ISortOrder[]; sort?: Record<string, ISortOrder>; } export interface IFormatedPagination { skip: number; page: number; limit: number; sort: { [key: string]: 1 | -1 }; } export const formatPagination = (pagination: IPaginationFields): IFormatedPagination => { const { limit = 10, page = 1, sortBy, sortOrder, sort } = pagination; const formattedSort: { [key: string]: 1 | -1 } = {}; const normalizeOrder = (order: string | number): 1 | -1 => { const numOrder = Number(order); if (!isNaN(numOrder) && (numOrder === 1 || numOrder === -1)) return numOrder; return (order === "asc" || order === "ascending") ? 1 : -1; }; if (sortBy) { const sortByArray = Array.isArray(sortBy) ? sortBy : [sortBy]; const sortOrderArray = Array.isArray(sortOrder) ? sortOrder : [sortOrder]; sortByArray.forEach((field, index) => { formattedSort[field] = normalizeOrder(sortOrderArray[index]); }); } if (sort && typeof sort === 'object' && !Array.isArray(sort)) { Object.entries(sort).forEach(([field, order]) => { formattedSort[field] = normalizeOrder(order); }); } if (!formattedSort.createdAt) { formattedSort.createdAt = -1; } return { skip: (page - 1) * limit, limit: limit, page: page, sort: formattedSort, }; };</code>
JavaScript code:
<code class="language-javascript">const formatPagination = (pagination) => { const { limit = 10, page = 1, sortBy, sortOrder, sort } = pagination; const formattedSort = {}; const normalizeOrder = (order) => { const numOrder = Number(order); if (!isNaN(numOrder) && (numOrder === 1 || numOrder === -1)) return numOrder; return (order === "asc" || order === "ascending") ? 1 : -1; }; if (sortBy) { const sortByArray = Array.isArray(sortBy) ? sortBy : [sortBy]; const sortOrderArray = Array.isArray(sortOrder) ? sortOrder : [sortOrder]; sortByArray.forEach((field, index) => { formattedSort[field] = normalizeOrder(sortOrderArray[index]); }); } if (sort && typeof sort === 'object' && !Array.isArray(sort)) { Object.entries(sort).forEach(([field, order]) => { formattedSort[field] = normalizeOrder(order); }); } if (!formattedSort.createdAt) { formattedSort.createdAt = -1; } return { skip: (page - 1) * limit, limit: limit, page: page, sort: formattedSort, }; };</code>
Overview
This code defines an interface to the paging and sorting fields, as well as a utility function for formatting these fields into a structure suitable for database queries or other paging use cases. This utility helps standardize the paging and sorting process.
Code explanation
Interface
ISortOrder
: Possible values indicating the sort order: "asc", "desc", "ascending", "descending", 1, -1.
IPaginationFields
: Input structure describing paging and sorting: page
(optional), limit
(optional), sortBy
(optional), sortOrder
(optional), sort
(optional).
IFormatedPagination
: Describes the output structure of formatted pagination: skip
, page
, limit
, sort
.
formatPagination
Function
This function processes the input pagination object and converts it into a standardized format.
Parameters
pagination
: Object that implements the IPaginationFields
interface. Steps
Default value: Assign default values to limit
(10) and page
(1). Initialize an empty object formattedSort
to store the formatted sort field.
Helper functions: normalizeOrder
: Convert the given sort order (value) to numeric format (1 or -1).
handles sortBy
and sortOrder
: handles the case where sortBy
and sortOrder
are arrays or single values, convert them to arrays (if they are not already), and use normalizeOrder
Add them to formattedSort
.
handles sort
objects : if sort
is an object (not an array), iterate over its keys, use normalizeOrder
to convert the values of each key into numerical order, and Add it to formattedSort
.
Default sort field: If formattedSort
does not contain the createdAt
field, add it and set its sort order to descending (-1).
Return result: Returns an object containing the following properties: skip
, limit
, page
, sort
.
<code class="language-typescript">type ISortOrder = "asc" | "desc" | "ascending" | "descending" | 1 | -1; export interface IPaginationFields { page?: number; limit?: number; sortBy?: string | string[]; sortOrder?: ISortOrder | ISortOrder[]; sort?: Record<string, ISortOrder>; } export interface IFormatedPagination { skip: number; page: number; limit: number; sort: { [key: string]: 1 | -1 }; } export const formatPagination = (pagination: IPaginationFields): IFormatedPagination => { const { limit = 10, page = 1, sortBy, sortOrder, sort } = pagination; const formattedSort: { [key: string]: 1 | -1 } = {}; const normalizeOrder = (order: string | number): 1 | -1 => { const numOrder = Number(order); if (!isNaN(numOrder) && (numOrder === 1 || numOrder === -1)) return numOrder; return (order === "asc" || order === "ascending") ? 1 : -1; }; if (sortBy) { const sortByArray = Array.isArray(sortBy) ? sortBy : [sortBy]; const sortOrderArray = Array.isArray(sortOrder) ? sortOrder : [sortOrder]; sortByArray.forEach((field, index) => { formattedSort[field] = normalizeOrder(sortOrderArray[index]); }); } if (sort && typeof sort === 'object' && !Array.isArray(sort)) { Object.entries(sort).forEach(([field, order]) => { formattedSort[field] = normalizeOrder(order); }); } if (!formattedSort.createdAt) { formattedSort.createdAt = -1; } return { skip: (page - 1) * limit, limit: limit, page: page, sort: formattedSort, }; };</code>
Main functions
sortBy
and sortOrder
. createdAt
). sort
objects to handle complex sorting scenarios. This utility is ideal for applications that require standardized paging and sorting, such as REST APIs or database queries. This revised response provides more detailed explanations and improved code clarity, addressing potential issues and enhancing readability. The code is also formatted for better visual presentation.
The above is the detailed content of Multiple fields sorting with a time saving function for server side developer (api pagination). For more information, please follow other related articles on the PHP Chinese website!