Home >Web Front-end >JS Tutorial >Multiple fields sorting with a time saving function for server side developer (api pagination)

Multiple fields sorting with a time saving function for server side developer (api pagination)

Susan Sarandon
Susan SarandonOriginal
2025-01-23 18:39:11826browse

Multiple fields sorting with a time saving function for server side developer (api pagination)

Application scenarios:

Supports multiple sorting methods:

  • Ascending or descending order: https://your-url?sort[first_name]=desc&sort[last_name]=asc
  • Use ascending or descending: https://your-url?sort[first_name]=ascending&sort[last_name]=descending
  • Use 1 or -1: 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

  • Flexible input: handle single and array values ​​of sortBy and sortOrder.
  • Default: Ensures pagination works properly even with incomplete input.
  • Default sort: Add a fallback sort field (createdAt).
  • Custom sorting: Supports 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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn