0

I'm having trouble with an async function. I'm making a query (using mongoose) to a mongodb and when I try to get the info back it yields undefined.

Here's my query to the db (nested within a function):

function kquery() {
  Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}

and here's my async/await function:

async function compare() {
  var ktick = await kquery();
  console.log(ktick);
}

compare();

These functions are both in the same file, and when I run it it gives me an 'undefined'. While, when I just run the query function and puts up a console.log(tick) instead of the return tick, I get the correct information:

{ _id: 59d1199cdbbcd32a151dcf21,
  mk: 'kraken',
  c: 430900,
  n: 1506875804217 }

I think, I'm messing up with the callback somewhere but I'm not sure where or how. Here's the full file:

const mongo = require('mongodb');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const server = mongoose.connect('mongodb://localhost/cryptoCollection', {
  useMongoClient: true
});

//Loading the mongoose schema:
const { Krakentick } = require('./kraken/model/krakenModel');
var now = Math.floor(new Date());

function kquery() {
  Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}


async function compare() {
  var ktick = await kquery();
  console.log(ktick);
}

compare();

Thanks in advance for your help!

Martin Carre
  • 1,157
  • 4
  • 20
  • 42
  • 2
    I only read to _"and here's my async/await function:"_ because that function indeed returns `undefined`.... Soooo.... what is the question? If that function is supposed to return something you should make it return something. Or do you mean the log output and not the return value? You cannot await `kQuery` it too does not return anything! No promise to wait for! Your `wait` statement "waits" for an immediate `undefined` return value. Looks like you forgot a `return` in front of `Krakentick.findOne? I hope that function returns a promise or it won't help. – Mörre Oct 01 '17 at 20:12
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Frxstrem Oct 01 '17 at 20:16
  • Hey Mörre! isn't the `return tick;` inside of my `kquery()` function supposed to return the tick that then goes into the async/await function `compare` to get logged ? – Martin Carre Oct 01 '17 at 20:17
  • 2
    Oh no, those `return` statements are completely useless. You need to read up on promises, the very basics.... your `async/await` is useless if you don't have a promise,and you don't, since it seems that function `findOne` is callback based. You should read a bit about the various asynchronous programming options in Javascript. – Mörre Oct 01 '17 at 20:17
  • OK Mörre! So there's my answer!! Thanks, I didn't know await/async could only be coupled up with promises! Could you post as the asnwer so that I can mark it as correct! Thanks a lot! – Martin Carre Oct 01 '17 at 20:19
  • 2
    Look for "promisifying callbacks" or something like that, it is very easy. Example: https://stackoverflow.com/a/41663320/544779 – Mörre Oct 01 '17 at 20:20
  • Yeah! Thanks, I mean I've done it in the past, I'm just too much of a noob to know that async/await only works with promises! :P Thanks again! – Martin Carre Oct 01 '17 at 20:21
  • 2
    Here's a good blog to follow: http://2ality.com/2016/10/async-function-tips.html – Mörre Oct 01 '17 at 20:22

2 Answers2

3

Your kquery function must return the promise :

function kquery() {
  return Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}
Arkerone
  • 1,971
  • 2
  • 22
  • 35
0

Just posting the promesified kquery function for reference:

function kquery() {
  return new Promise((resolve, reject) => {
    Krakentick.findOne(
      {
        iname: 'btcusd',
        n: { $lt: now }
      },
      'mk c n',
      function(err, tick) {
        if (err) {
          reject(err);
        } else {
          resolve(tick);
        }
      }
    );
  });
}

The accepted answer was the one above although it had been discussed and documented previously in the comments by Mörre! I just wanted to leave it there in case it helps someone!

Thanks again for your valuable help!

Martin Carre
  • 1,157
  • 4
  • 20
  • 42