1

I want to use gridfs-stream in a nodejs application.

A simple example is given in the documentation:

var mongoose = require('mongoose');
var Grid = require('gridfs-stream');
Grid.mongo = mongoose.mongo;

mongoose.connect('mongodb://localhost:27017/test');

// make sure the db instance is open before passing into `Grid`
mongoose.connection.once('open', function () {
  var gfs = Grid(mongoose.connection);

  // all set!
})

My problem is described by the comment:

make sure the db instance is open before passing into Grid

I try to use gfs in a post request. Now when the code gets initialized, the gfs variable is not defined yet.

api.post('/upload', function(req, res) {
  req.pipe(gfs.createWriteStream({
    filename: 'test'
  }).on('close', function(savedFile){
    console.log('file saved', savedFile);
    return res.json({file: savedFile});
  }));
})

Initializing my route from a callback seems kind of odd. I read in this post (Asynchronous initialization of Node.js module) that require('') is performed synchronous, and since I rely on the connection being established, I'm kind of forced to wait

Basically I'm not sure if I should use a async pattern on startup now, or if I just miss a more elegant way to solve this.

2
  • It's pretty common to apply all your stuff and create app, and then start to listen for incoming requests. Therefore by the time you get first request, the database will be connected. And there is nothing bad waiting for it and executing a callback. It's even better to use EventEmitter and just emit an event - it's easy, flexible and decoupled. Commented Feb 12, 2016 at 18:11
  • ok, so i go for that:) thanks for the fast reply Commented Feb 12, 2016 at 18:19

1 Answer 1

0

I have a very similar problem with my server. In my case I am reading https certs asynchronously, the software version from git asynchronously and I want to make sure I have it all together by the time the user comes to log in so I can pass the software version back as a reply to login.

The solution is to use promises. Create the promises on user start up for each activity. Then in the code where you want to be sure its all ready, just call then on either the promise itself or Promise.all(array of promises).then()

Here is an example of what I am doing to read the ssl certs to start the server

  class Web  {
    constructor(manager,logger) {
      var self = this;
      this.server = false;
      this.logger = logger;
      var key = new  Promise((resolve,reject) => {
        fs.readFile(path.resolve(__dirname, 'key.pem'),(err,data) => {
          if (err) {
            reject(err);
          } else {
            resolve(data);
          }
        });
      });
      var cert = new Promise((resolve,reject) => {
        fs.readFile(path.resolve(__dirname, 'certificate.pem'), (err,data) => {
          if (err) {
            reject(err);
          } else {
            resolve(data);
          }
        });
      });

      Promise.all([key,cert]).then(values => {
        var certs = {
          key: values[0],
          cert: values[1],
        };
        return certs;
      }).then(certs => {
        self.server = require('http2').createServer(certs,(req,res) => {
        // NOW Started and can do the rest of the stuff
        });
        self.server.listen(...);
      });
 NEEDS SOME MORE CLOSING BRACKETS
Sign up to request clarification or add additional context in comments.

Comments

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.