-2

I've spent so much time trying to find the answer to this on here and come up with nothing. Hoping someone can enlighten me..

I have code which is making an async call to a database and returning data in a callback function (in my case I'm using MongoClient, which returns a Promise). However, I can't work out how to use the resulting data to actually set function-level variables - whenever I try to do it the resulting value that I log is either undefined or a pending Promise object.

There's lots of posts on this subject but I can't find any methods that work when I try to apply them. Any and all help gratefully received!

function lookupOneDbEntry(key, value) {

    var responseData = "initial data"

    // search for the entry in the database
    db.collection("my_collection").findOne({key: value}, function(err, result) {
      if (err) {
        //if database throws an error
        responseData = "db error";
      } 
      else {
        // if the entry is found, return the data
        responseData = result;
      }
    });

    return responseData;

  }

EDIT: I am aware of other posts on this (like this one here and, while exhaustive documentation is useful to an extent, I;m having trouble using this information practically in a real-life implementation like the one above. Hence my question here.

Community
  • 1
  • 1
user2521119
  • 165
  • 2
  • 14
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Nov 19 '16 at 13:43
  • That question you linked really does have all the information you need. Mr Kling's answer has an extensive amount of explanation and various solutions for different situations. – Pointy Nov 19 '16 at 13:52
  • Can you show how you are trying to use the Promise? – Victory Nov 19 '16 at 14:04
  • @Pointy which bit of the mammoth document exactly? As I said I've tried implementation of this - e.g. restructuring my code to use callbacks that set the function-level variable, and nothing seems to work. I'm sure other people other than me would appreciate a real-life example rather than dealing with abstract scenarios - I just know if I have to read another example with foo in it my head's going to explode. – user2521119 Nov 19 '16 at 14:05
  • @Victory I'm not wanting to use it directly, it's just what MongoClient is using. In the callback function in my example I'm just working with the resulting data after the promise has completed. – user2521119 Nov 19 '16 at 14:10
  • Are you sure its a promise and not just a callback? Can you do `new Promise()` or does that throw an error? – Victory Nov 19 '16 at 14:19

2 Answers2

0

Async calls happens outside of the call stack that you are on. you can't return it onto the current stack.

So we use the promises to hook into the results of our call.

function lookupOneDbEntry(key, value) {
  return new Promise(function (resolve, reject) {
    // search for the entry in the database
    db.collection("my_collection").findOne({key: value}, function(err, result) {
      if (err) {
        //if database throws an error
        reject(err);
      }
      else {
        // if the entry is found, return the data
        resolve(result);
      }
    });
  });
}

lockupOneDbEntry('myKey', 'myValue').then(function (result) {
  console.log('result', result);
}, function (err) {
  console.log("error!", err);
});
Victory
  • 5,811
  • 2
  • 26
  • 45
  • Appreciate the effort, but this didn't work for me. Thanks for putting me onto the idea of resolving the promise though, I managed to cobble together a solution based on that idea :) – user2521119 Nov 19 '16 at 16:29
  • No problem. If it was helpful you should upvote and if you found a solution explain it, you can answer your own questions on here, its encouraged. – Victory Nov 19 '16 at 22:36
0

After a long while of experimenting I've finally managed to do it - I didn't need any fancy callbacks or additional Promises in the end, I just removed the optional callback in the database request and instead processed the returned promise separately.

function lookupOneDbEntry(key, value) {

    var responseData = "initial data";

    var solution = db.collection("accounting_module").findOne({key: value});

    solution.then(function (result) {
      // validation of result here
      responseData = result;
    });

    return responseData;
}
user2521119
  • 165
  • 2
  • 14