Problem with Database querying in NodeJS

I’m working on the URL Shortener API, I store the data in the database and when i try to retrieve it with a get route, this happens:
this is the code

app.route('/:short_url_index')
  .get(function (req, res) {

    MongoClient.connect(Mongo_URI, function (err, db) {
      if (err) return console.log('Error connecting to the Database', err);

      var short_url_index = parseInt(req.params.short_url_index);

      db.collection('urls').findOne({
        short_url_index: short_url_index
      }, function (err, doc) {
        res.redirect(doc.original_url);
      });
      db.close();
    });

  });

i’m basically trying to query the database by the short url and get the original url, but i get this error in the cmd:

Node.js listening ...
*
*
C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb\lib\utils.js:123
    process.nextTick(function() { throw err; });
                                  ^

TypeError: Cannot read property 'original_url' of null
    at C:\Users\hamza\Desktop\url_shortener\server.js:100:25
    at handleCallback (C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb\lib\utils.js:120:56)
    at C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb\lib\collection.js:1417:5
    at handleCallback (C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb\lib\utils.js:120:56)
    at C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb\lib\cursor.js:682:5
    at handleCallback (C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb-core\lib\cursor.js:171:5)
    at setCursorNotified (C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb-core\lib\cursor.js:515:3)
    at C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb-core\lib\cursor.js:590:16
    at queryCallback (C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb-core\lib\cursor.js:232:18)
    at C:\Users\hamza\Desktop\url_shortener\node_modules\mongodb-core\lib\connection\pool.js:469:18
[nodemon] app crashed - waiting for file changes before starting...

but when i try to log the document retrieved from the database, i get it correctly and it’s not undefined

findOne callback needs to check the error parameter - it will show the problem

Added the error check, and i’m still having the same problem

if (err) res.status(400).send({error: err});

what does the error say? since there is an error you cannot use the doc parameter

It just throws the same error: and i don’t see any response in postman

the problem is db.close() is called right after findOne which is async

what’s the solution to this? should i use promises?

Here’s what i did:

db.collection('urls').findOne({
        short_url_index: short_url_index
      }).then(function (doc) {
        res.redirect(doc.original_url);
        console.log(doc);
      }).catch(function (err) {
        res.send({error: err});
      });
      db.close();

and this is the response

{ _id: 59aadc0b918df030bcc216d7,
  original_url: 'www.google.com',
  short_url_index: 3432,
  short_url: 'http://localhost:3000/3432' }

this makes it way more confusing, if i can get the object back, why can’t i get its property?

you cannot close the db until the work is done - the work is done in the findOne callback - so close must be called in the callback

promises make async code look cleaner - arguably they make async solutions easier but you must understand promises first - and the best use of promises now is with async/await supported in node

your promises version has the same async logic problem aka race condition - a little easier to fix with promises - put db.close() in a final then

in the future there may be a promises finally

Even if i put the db.close() call into the callback, it does the same thing.
I don’t think how i handle the async is important because event if i comment out the close call it does the same thing.
and this is the response i get from the catch() call

{
    "error": {}
}