[Fixed] POST request for paginating, sorting results

Issue

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

Leave a Reply

(*) Required, Your email will not be published