1

I want to use an module to get and process data from my MongoDB database. (It should generate an object that represents my Express.js site's navbar)

I thought of doing something like this:

var nav = { Home: "/" };
module.exports = function() {
  MongoClient.connect(process.env.MONGO_URL, function(err, db) {
    assert.equal(err, null);
    fetchData(db, function(articles, categories) {
      combine(articles, categories, function(sitemap) {
        // I got the data. What now?
        console.log("NAV: ", nav);
      })
    });
  });
};

var fetchData = function(db, callback) {
  db.collection('articles').find({}).toArray(function(err, result) {
    assert.equal(err);
    articles = result;
    db.collection('categories').find({}).toArray(function(err, result) {
      assert.equal(err);
      categories = result;
      db.close();
      callback(articles, categories);
    });
  });
};

var combine = function(articles, categories, callback) {
  categories.forEach(function(category) {
    nav[category.title] = {};
    articles.forEach(function(article) {
      if(article.category == category.name) {
        nav[category.title][article.title] = "link";
      }
    })
  });
  callback(nav);
};

As of line 6, I do have all data I need.

(An object, currenty like { Home: '/', Uncategorized: { 'Hello world!': 'link' } })

But since I'm in an anonymous function, I don't know how to return that value. I mean, return would just return it the function that called it... And in the end, MongoClient.connect would receive my data.

If I set a variable instead, it would be set as module.exports returned before Node can even query the data from the database, right?

What can I do in order to make this work?

It should result in some kind of function, like

var nav = require('nav');
console.log(nav());

Thanks in advance!

3
  • You can always return the desired data by using callbacks. Commented Jun 19, 2016 at 17:28
  • @Nonemoticoner How? I'm new to Node.js, sorry. Commented Jun 19, 2016 at 17:33
  • I have posted an answer. Hopefully correct as I don't have an ability to test it right now. Write a comment if you encounter any errors. Commented Jun 19, 2016 at 17:55

3 Answers 3

1

Add another callback:

var nav = { Home: "/" };
module.exports = function(cb) {
    MongoClient.connect(process.env.MONGO_URL, function(err, db) {
        assert.equal(err, null);
        fetchData(db, function(articles, categories) {
            combine(articles, categories, function(sitemap) {
                cb(sitemap);
            })
        });
    })
});

And then use this way:

var nav = require('nav');
nav(function(sitemap){ console.log(sitemap); });
Sign up to request clarification or add additional context in comments.

Comments

1

You can use mongoose module or monk module. These modules have been tested properly .

Just use

npm install mongoose or monk

1 Comment

That should still work with the official module, somehow. If I can't find an solution, I'll try mongoose. Thanks for the suggestion!
0

The suggestion about mongoose is great and you can look into it, however I think you've already done the job with the fetching of the data from the db. You just need to access it in your main node flow.

You can try this:

module.exports.generateNav = function() {
  MongoClient.connect(process.env.MONGO_URL, function(err, db) {
    assert.equal(err, null);
    var output = fetchData(db, function(articles, categories) {
      combine(articles, categories, function(sitemap) {

      })
    });
    return (output);
  });
};

And then in your main application you can call it in the following way:

var nav = require('nav');
navigation = nav.generateNav();
console.log(navigation);

3 Comments

That was also my idea. But, you seem to not really understand my problem... If I add a return statement to fetchData, the data is passed to db.collection('categories').find({}).toArray, which does not make any sense...
fetchData function is asynchronous. I hardly see that work the way you written that here. output will be most likely undefined.
@Nonemoticoner Correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.