0

I am new to RESTful APIs and I've successfully implemented the GET and DELETE methods for my API (GET localhost:4000/api, DELETE localhost:4000/api on Postman works fine).

What I want to implement now is to specify the order in which to sort each specific field where 1 is ascending and -1 is descending. For example,

If I do localhost:4000/api/users?sort = { fieldName : 1 }

This will return a list of users sorted by 'fieldName'.

I tried to do

router.get('/', function(req, res) {
  var sort = req.query.sort;

  user
   .find({})
   .sort({"name": sort}) 
   .exec(function(err, users) {
      if(err){
          res.status(404).send({
              message: err,
              data: []
          });
      } else {
          res.status(200).send({
              message: 'OK',
              data: users
          });
      }
  });
});

But since the "name" part is hard-coded, it only works for names. I want to let the user specify the field name and sort the list based on it.

What do I have to add?

EDIT: This is how my data looks like

{
    "message": "OK",
    "data": [
        {
            "_id": "59faba588f3f6211ac7db43c",
            "name": "Kim2",
            "email": "[email protected]",
            "__v": 0,
            "dateCreated": "2017-11-02T06:25:28.225Z",
            "pendingTasks": []
        },
        {
            "_id": "59facf56e8c5663343d4b644",
            "name": "Minnie Payne",
            "email": "[email protected]",
            "__v": 0,
            "dateCreated": "2017-11-02T07:55:02.552Z",
            "pendingTasks": []
        },
        {
            "_id": "59fb699c3c00c60990fa6edb",
            "name": "jerry watson",
            "email": "[email protected]",
            "__v": 0,
            "dateCreated": "2017-11-02T18:53:16.637Z",
            "pendingTasks": []
        }, ...

EDIT2

  user
   .find({})
   .sort('name') 
   .exec(function(err, users) {
      if(err){
          res.status(404).send({
              message: err,
              data: []
          });
      } else {
          res.status(200).send({
              message: 'OK sorted',
              data: users
          });
      }
  });
2
  • req.query items all all "strings". If you want an object from JSON as parameter values, then use JSON.parse. i.e .sort({ name: JSON.parse(req.query.sort) }) where req.query.sort is the "string" '{ "fieldName": 1 }'. Noting that JSON expects quoted "keys". Commented Nov 3, 2017 at 2:48
  • Sorry, could you actually elaborate your solution in the answer? I think I get the idea, but I really don't get how to do this in the code. Commented Nov 4, 2017 at 2:52

1 Answer 1

1

What you want to do is to name an object property by a string. To do it you can do something like:

var string = 'name'
var obj = {}
obj[string] = 'val'
console.log(obj) // {name: 'val'}

So, in your example:

router.get('/', function(req, res) {
  var sort = req.query.sort;
  var name = req.query.name;
  var obj = {}
  obj[name] = sort

  user
   .find({})
   .sort(obj) 
   .exec(function(err, users) {
      if(err){
          res.status(404).send({
              message: err,
              data: []
          });
      } else {
          res.status(200).send({
              message: 'OK',
              data: users
          });
      }
  });
});

EDIT: solution with localhost:4000/api/users?sort={fieldName: 1}

router.get('/', function(req, res) {
  let obj = JSON.parse(req.query.sort)

  user
   .find({})
   .sort(obj) 
   .exec(function(err, users) {
      if(err){
          res.status(404).send({
              message: err,
              data: []
          });
      } else {
          res.status(200).send({
              message: 'OK',
              data: users
          });
      }
  });
});
Sign up to request clarification or add additional context in comments.

10 Comments

But isn't this pretty much hard coding the field 'name' ? I want to specify the field name on the URL directly. e.g. localhost:4000/api/users?sort={fieldName: 1} where fieldName can be any existing field like 'name', 'id', 'date', etc.
it's exactly what the code does! look at line 3. The name variable is taken from query string
Thanks! I just tried but it seems like it's not sorting. What I actually wanted was sorting based on whether the value for the sort query is -1 or 1 (1- ascending; -1 - descending). So that localhost:3000/api/users?sort={"name": 1} this would sort the names in ascending order.
if you want to pass directly {"name":1} in the query string, you need to parse string. So obj = JSON.parse(req.query.fieldname)
no. i proposed you two solution. the first one (in my answer, where a edited your code) you can use your api in this way: localhost:3000/api/users?name=yourkey&sort=1. Then, my 2nd comment i proposed an alternative solution based on your querystring format (you want to send to server localhost:3000/api/user?sort={yourkey: 1}. In this scenario, you should JSON.parse(req.query.sort). This will create an object that you can pass to your sort function. Both the solution are not hardcoded and take the key name you want order to from query string.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.