-1

I want to access the data in document in the function were I handle the Item, How can I put the variable document.date in the itemstring?

function pagelist(items, res) {
    var db = db_login;
    result = "<html><body><ul>";
    items.forEach(function(item) {
        console.log(item)
        db.collection('insights').findById(item._id , function(error, document) {
            console.log(document)
            if (error || !document) {
                res.render('error', {});
            } else {
            **console.log(document.date) //this value is displayed**
            }
        })

        **console.log(document.date)//this value is undefind**

        itemstring = "<li>" + item._id + "<ul><li>" + item.textScore +
            "</li><li>" + item.created + "</li><li>" + item.document +
            "</li></ul></li>";
        result = result + itemstring;
    });
    result = result + "</ul></body></html>";
    return result;
}
Rhumborl
  • 16,349
  • 4
  • 39
  • 45
josef
  • 255
  • 1
  • 6
  • 14
  • 1
    `findById` is async, so see this related question: http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – JohnnyHK Oct 28 '14 at 12:41

2 Answers2

0

The current answers all miss a key point, that your "child" function is a callback from an asyn function. It does not execute before the rest of your "parent" function does.

function pagelist(items, res) {
    // ... (1)
    items.forEach(function(item) {
        db.collection('insights').findById(item._id, function(error, document) {
            // this will not execute (4)
        });
        // before this (2)
    });
    // or this (3)
    // Actual order will be in that of (numbers)
    return result;
}

Your only option is you make your parent function behave the same way that your db function does. I.e. make it asyn too.

function pagelist(items, done) { // <= "done"
    items.forEach(function(item) {
        db.collection('insights').findById(item._id, function(error, document) {
            // Now you can call done with document that is available here
            done(document); // or done(document.date); w/e
        });
    // return result; // Returns are useless* in asyncs
}

Wherever you're calling pagelist() from pass it a callback function "done" and do stuff in there

app.use(function(req, res){
    pagelist(items, function(document){ // <= this will be the "done" function
        var itemstring = document.date;
        // do whatever you want with the document here.
        res.render(~);
        console.log(document.date);
    });
});
laggingreflex
  • 32,948
  • 35
  • 141
  • 196
-1

Try this: Assign local variable document to global variable doc and access it in outside of the function;

function pagelist(items, res) {
     var db = db_login;
     var doc;
     result = "<html><body><ul>";
     items.forEach(function(item) {
        console.log(item)
        db.collection('insights').findById(item._id , function(error, document) {
        console.log(document)
        doc=document; // assignment of the local variable to global variable
        if (error || !document) {
            res.render('error', {});
            } else {
            console.log(document.date)
            }})

     console.log(doc.date) // here is use of global variable

     itemstring = "<li>" + item._id + "<ul><li>" + item.textScore +
       "</li><li>" + item.created + "</li><li>" + item.document +
       "</li></ul></li>";
      result = result + itemstring;
     });
    result = result + "</ul></body></html>";
    return result;
   }

Enjoy :)

Amy
  • 4,034
  • 1
  • 20
  • 34