Node/Express/MongoDB Project 3: I don't understand

I declared this in server.js

var num = 1

But then I tried to assign the num from my counter in MongoDB, before i send response like this

app.route('/api/shorturl/new')
  .post((req, res) => {
    let regex = /^https?:\/\//
    if (regex.test(req.body.url) === true) {
      urlData.findOne({ name: 'counter' }).select(['count']).exec(async (err, count) => {
        if (err)
          return console.log(err);
        num = await count.toObject().count;
      })
      incr()// to increment the counter (this works)
      urlData.create({ url: req.body.url, code: num }, (err) => {
        if (err)
          console.log(err);
      })
      res.send({ original_url: req.body.url, short_url: num })
    }
    else {
      res.send({ error: 'Invalid URL' })
    }
    console.log('Data Sent')
  })

I got this {"original_url":"https://www.facebook.com","short_url":1}

Question 1: What is going on, why doesn’t the num variable gets updated before the respond. Is it because of something regarding to async function? I have no clue.

Question 2: The short_url delayed from my counter. It responds 16 when my counter is 18. Why?

Also, any feedback would be appreciated. I think my method is super wrong (declaring var in server.js).

Thanks.

Challenge: URL Shortener Microservice

Link to the challenge:

Hi there,

What is happening is that you are actually executing an async function, and inside of it you are using await. But you are not waiting that expression to get resolved.

At the time that you send your response your async function is still executing and probably not updating the value of num.

you should wrap your res.send() conde inside that function or use ‘then’ instead

Something like that:

app.route('/api/shorturl/new')
  .post((req, res) => {
    let regex = /^https?:\/\//
    if (regex.test(req.body.url) === true) {
      urlData.findOne({ name: 'counter' }).select(['count']).exec(async (err, count) => {
        if (err)
          return console.log(err);
        num = await count.toObject().count;
        incr()// to increment the counter (this works)
        urlData.create({ url: req.body.url, code: num }, (err) => {
        if (err)
          console.log(err);
       })
       res.send({ original_url: req.body.url, short_url: num })
      })
    }
    else {
      res.send({ error: 'Invalid URL' })
    }
    console.log('Data Sent')
  })

or if .exec() method creates a promisse you could write something like

app.route('/api/shorturl/new')
  .post((req, res) => {
    let regex = /^https?:\/\//
    if (regex.test(req.body.url) === true) {
      urlData.findOne({ name: 'counter' }).select(['count']).exec(async (err, count) => {
        if (err)
          return console.log(err);
        num = await count.toObject().count;
      }).then( () => {
           incr()// to increment the counter (this works)
           urlData.create({ url: req.body.url, code: num }, (err) => {
           if (err)
           console.log(err);
      })
      res.send({ original_url: req.body.url, short_url: num })
      })
    }
    else {
      res.send({ error: 'Invalid URL' })
    }
    console.log('Data Sent')
  })
1 Like

Hi thanks for the answer, I have actually solved this!