Search code examples
javascriptmongodbpromisereturn-valuenative-code

Return MongoDB query result as variable instead of to console


In a javascript file named db_to_var.js I have the following function that succesfully prints the array returned by a query to database test_db, to console.log() . (E.g. a database called cars which have a key name describes the brandname, e.g. toyota, hyunday,volvo.). The method is called with: console.log("listCars function call="+listCars()); and contains:

function listCars() { 
    car_and_name_grandparent = MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbo = db.db("testdb");

        car_and_name_parent = dbo.collection("cars").find({}, { projection: { _id: 0, name: 1} }).toArray(function(err, result) {
            if (err) throw err;
            car_and_name = result;
            db.close();

            console.log("car_and_name="+car_and_name);
            return car_and_name;
        });

        return car_and_name_parent;
    });

    return car_and_name_grandparent;
}; 

However, car_and_name_parent remain undefined because the car_and_name, which is filled correctly is not actually returned to the car_and_name_parent. This led me to investigate, and I looked into:

  1. The documentation of .toArray(), which is not supposed to take an argument in the first place. Hence I inspected what dbo.collection("cars").find({}, { projection: { _id: 0, name: 1} }).toArray() actually returns, which is an [object Promise].

    1.a One can't evaluate a Promise directly but has to use then, await or async.

    1.b I am able to convert the Promise into function then() { [native code] } using .then but I have not found how to further evaluate this expression to retrieve the list out of "[native code]". The await returns error saying SyntaxError: await is only valid in async function, whereas async car_and_name.then returns error SyntaxError: Unexpected identifier.

  2. I also tried passing a global variable named carNames into the functions, and to assign it value car_and_name, but I am currently not able to succesfully pass the global variable to inside the .toArray(..) as console.log(carNames); is undefined when I do that, in that position.

How can I return the car_and_name variable to a variable outside the function listCars()?


Solution

  • Here's how you would do it with async await.

    async function listCars() {
        let db = await MongoClient.connect(url);
        let dbo = db.db("testdb");
        return await dbo.collection("cars").find({}, { projection: { _id: 0, name: 1} }).toArray()
    }
    
    listCars().then(cars => {
        console.log(cars); //You will get your results here
    })
    

    The mongoDB queries in nodejs like the one above are asynchronous so you cannot get the return value in a variable directly. You either have to use a callback function or .then() to use promises like in the example above.

    The toArray() function you are using is a MongoDB method, the one you mentioned in your question is a jQuery one. This is the correct documentation for your reference -> https://docs.mongodb.com/manual/reference/method/cursor.toArray/

    Hope it helps!