最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Return MongoDB query result as variable instead of to console - Stack Overflow

programmeradmin1浏览0评论

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()?

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()?

Share Improve this question asked Nov 17, 2019 at 10:38 a.t.a.t. 2,7997 gold badges45 silver badges96 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

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./manual/reference/method/cursor.toArray/

Hope it helps!

Your method is making an asynchronous call which is instantly executed as a Promise before the value you're looking for is retrieved.

I'd remend wrapping your method in a promise.

function listCars() { 
    return new Promise((resolve, reject) => {
       MongoClient.connect(url, function(err, db) {
        if (err) reject(err);
        var dbo = db.db("testdb");

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

Then you can use it like this.

listCars()
    .then(carNames => {
        // Use your variable here.
    })
    .catch(err => throw err);

You can also use listCars as a helper method in an async method like so.

const carWork = async function() {
    try {
       const carNames = await listCars();
       // ....
    } catch (err) {
        throw err;
    }
}

You can use async/await. But you didn't used it right way. You got syntax error that says you can use await only in async function. So you can write your code like this,

async function listCars() { 
 try{
    db = await MongoClient.connect(url);
    var dbo = db.db("testdb");
    car_and_name_parent = await dbo.collection("cars").find({}, { 
      projection: { _id: 0, name: 1} }).toArray();
   return car_and_name_parent
}catch(err){
  throw err;
 }
}; 
发布评论

评论列表(0)

  1. 暂无评论