1

I have a web page view that requires two sets of mongoose documents, one for "complete tasks" and one for "incomplete tasks."

Here is my current code:

router.get('/', (req, res) => {
  Task.find({'completed': false}) // Finding all incomplete tasks
    .exec()
    .then((incompleteTasks) => {
      Task.find({'completed': true}) // Finding all complete tasks
        .exec()
        .then((completeTasks) => {
          res.render('tasks/tasks', {
            title: 'Tasks',
            incompleteTasks: incompleteTasks,
            completeTasks: completeTasks,
          });
        });
    });
});

Is there a way to make this more elegant? Right now, it isn't too bad, but if I had to split up my tasks into more than sets, the code would get pretty messy.

What I thought of was to make the code have the following structure:

let incompleteTasks = /* Get INCOMPLETE tasks */
let completeTasks = /* Get COMPLETE tasks */
res.render('tasks/tasks', {
  title: 'Tasks',
  incompleteTasks: incompleteTasks,
  completeTasks: completeTasks,
});

However, because of the asynchronous nature of mongoose queries, I'm not sure how to do this.

Any suggestions?

Frank
  • 414
  • 4
  • 15

2 Answers2

1

Using asynchronous can be helpful.

router.get('/', async (req, res) => {
    try{
        incompleteTasks = await Task.find({'completed': false}).exec();
        completeTasks = await Task.find({'completed': true}).exec()
        res.render('tasks/tasks', {
                title: 'Tasks',
                incompleteTasks: incompleteTasks,
                completeTasks: completeTasks,
              });
    }
    catch (e){
        //handle your error here
    }
});
Milad Aghamohammadi
  • 1,866
  • 1
  • 16
  • 29
0

Since incompleteTasks and completeTasks don't depend on each other, queries should be performed in parallel.

router.get('/', (req, res, next) => {
  Promise.all([
    Task.find({'completed': false}),
    Task.find({'completed': true})
  ]).then(([incompleteTasks, completeTasks]) => {
      res.render('tasks/tasks', {
        title: 'Tasks',
        incompleteTasks: incompleteTasks,
        completeTasks: completeTasks,
      });
    });
  })
  .catch(next);
});

It can be written with async..await:

router.get('/', async (req, res, next) => {
  try {
    const [incompleteTasks, completeTasks] = await Promise.all([
      Task.find({'completed': false}),
      Task.find({'completed': true})
    ]);
    res.render('tasks/tasks', {
      title: 'Tasks',
      incompleteTasks: incompleteTasks,
      completeTasks: completeTasks,
    });
  } catch (err) {
    next(err);
  }
});

Since Express doesn't support promises, all rejections should be handled as a rule of thumb.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565