antjanus
antjanus

Reputation: 997

How do you set and retrieve an instance of BookshelfJS using Express?

I'm trying to use Bookshelf along with Express 4.0 and can't seem to get them working together or rather, I can't seem to follow "best practices". The Bookshelf docs mention that one should always reuse the same instance of it throughout the app. It even lists an example:

// When the app starts
var app = express();
var knex = require('knex')(dbConfig);
var bookshelf = require('bookshelf')(knex);

app.set('bookshelf', bookshelf);

// elsewhere, to use the bookshelf client:
var bookshelf = app.get('bookshelf');

var Post = bookshelf.Model.extend({
  // ...
});

However, I can't seem to get it working when I have to use app.get() in a separate file. For example, here's my app.js file (the root of my entire app):

var express = require('express');
var app = express();

var db = require('./server/db/db');
app.set('bookshelf', db);

var api = require('./server');

app.use(api);

Here's my db.js file that gets required above:

var express = require('express');
var app = express();

var knex = require('knex')({ //my db settings go here });
var bookshelf = require('bookshelf')(knex);

module.exports = bookshelf;

The above code works if I require it directly. Here's where the issue turns up. Whenever I want to actually use the bookshelf connection, no matter what file I'm in, I follow the same process but it fails and "bookshelf" is always undefined. Here's an example of an index.js file that's required and called "api" in the app.js:

var express = require('express');
var app = express();
var db = app.get('bookshelf');
console.log(db);

DB always comes up as undefined. Whenever I try to make a new Model, I use the same process except I do an db.Model.extend({}) and trying to access the Model property throws an error (because it's undefined).

From what I can use both Bookshelf and Express docs agree that this should work and it doesn't. Any ideas?

Upvotes: 1

Views: 943

Answers (1)

teleaziz
teleaziz

Reputation: 2240

This line creates a new app every time you call it:

var myApp = express();

If you want to set or get variables from the same app, you'll have to pass it as an argument.

var api = require('./server')(myApp);

And then in your api module:

module.exports = function(app){
    var db = app.get('bookshelf');
//....
};

On a side note: you don't have to worry about singletons in Node.js all you have to do is just require it.

var db = require('./path/to/db/config');

It'll only be instantiated once and cached for later calls.

Upvotes: 6

Related Questions