Search code examples
javascriptnode.jsmongodbexpresshttp-method

POST request for paginating, sorting results


I am currently doing a GET request that uses a bunch of methods that I wrote to query the database and display them. This works great, but I want to make it a POST request method so that the methods do not have to depend on req.query, deal with a json body instead of a string of URL params which would would facilitate the url string not to have anything else except the endpoints and make it as dynamic as possible. Any idea how to do this?

This is my controller method:

exports.getBooks = async (req, res, next) => {

    const bookList = new BookList(Book.find(), req.query)
        .filter()
        .sort()
        .paginate();

    const books = await bookList.query;
    
    res.status(200)
        .json({
            books,
        });
};

This is the BookList class that has all the methods:

class BookList {
    constructor(query, queryString) {
        this.query = query;
        this.queryString = queryString;
    }

    filter() {
        const queryObj = { ...this.queryString };
        const excludedFields = ['page', 'sort', 'limit', 'fields'];
        excludedFields.forEach(el => delete queryObj[el]);

        let queryStr = JSON.stringify(queryObj);

        this.query = this.query.find(JSON.parse(queryStr));

        return this;
    }

    sort() {
        if (this.queryString.sort) {
            const sortBy = this.queryString.sort.split(',').join(' ');
            this.query = this.query.sort(sortBy);
        } else {
            this.query = this.query.sort('-createdAt');
        }

        return this;
    }

    paginate() {
        const page = Number(this.queryString.page) || 1;
        const limit = Number(this.queryString.limit) || 100;
        const skip = (page - 1) * limit;

        this.query = this.query.skip(skip).limit(limit);

        return this;
    }
}
module.exports = BookList;

Solution

  • This is what worked for me:

    exports.getBooks = async (req, res, next) => {
        let bookBody = req.body
        const bookList = new BookList(Book.find(), req.query)
            .filter(bookBody, req)
            .sort()
            .paginate();
    
        const books = await bookList.query;
        
        res.status(200)
            .json({
                books,
            });
    };
    
    filter(bookBody, req) {
            const filterBooks = bookBody.filter
            const bookId = req.params.bookId
    
            let requiredFilter
            if (filterBooks) {
                requiredFilter = {bookStatus: filterBooks.bookStatus, bookId};
            } else {
                requiredFilter = { bookId}
            }
            this.query = this.query.find(requiredFilter)
    
            return this;
        }