massive.connectSync not a function - javascript

Why do I get this error, massive.connectSync is not a function when I run server.js. It works on my mac, but not my windows. Please help solve this enter code hereerror
var express = require("express");
var app = express();
var http = require('http');
var massive = require("massive");
var connectionString = "postgres://massive:#localhost/MarketSpace";
// connect to Massive and get the db instance. You can safely use the
// convenience sync method here because its on app load
// you can also use loadSync - it's an alias
var massiveInstance = massive.connectSync({connectionString : connectionString})
// Set a reference to the massive instance on Express' app:
app.set('db', massiveInstance);
http.createServer(app).listen(8080);

Synchronous functions are no longer supported, and the connect function itself no longer exists, it's all promises all the way:
var express = require("express");
var app = express();
var http = require('http');
var massive = require("massive");
var connectionString = "postgres://massive:#localhost/MarketSpace";
massive(connectionString).then(massiveInstance => {
app.set('db', massiveInstance);
http.createServer(app).listen(8080);
});
Note that massive requires node > 6. If you are using and older version you'll need to update node in order to use massive.
Docs

Related

Logger is not a function error in Node.js

As in my previous questions I said, I am trying to create an HTTP server, testing some middlewares codes, but in my code right now is giving basically the same error from another times, but I can't see where I am getting this wrong.
My code :
logger.js
var http = require('http');
var connect = require('connect');
var app = connect();
// setup logger middleware
app.use(connect.logger());
// actually respond
app.use(function(req, res) {
res.end('Hello World!');
});
http.createServer(app).listen(8080);
He points out to the connect.logger() even if I am using app.use(), still gives me this error.
connect.logger is not a function
Connect no longer comes with a built-in logger! Try using some logging library like morgan
var http = require('http');
var connect = require('connect');
var logger = require('morgan');
var app = connect();
// setup logger middleware
app.use(logger("combined")); //Without one string in logger() it will give deprecated morgan format, so it needs to use some string for work, the documentation it say so.
// actually respond
app.use(function(req, res) {
res.end('Hello World!');
});
http.createServer(app).listen(8080)

Require (the same instance of) socket.io in multiple modules

I am a bit confused, about how to require and use modules in Node.js.
My scenario is the following:
I wrote a complete server in one single file, which uses Socket.io for realtime communication.
Now the index.js became pretty big, and I want to split the code into several modules to make it more managable.
For example I have some functions for serving a Survey to the clients, and getting back their answers. I put all those functions in a seperate module, and require it in the index.js. Works fine so far.
The only thing I am concerned about is, if there is another way to use the SAME socket instance inside the module.
My current coding looks like this:
index.js:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey');
io.on('connection', function (client) {
client.on('getCurrentQuestion', function (data) {
Survey.getCurrentQuestion(parseInt(data.survey_id), client.id);
});
});
server.listen(port, server_url, function () {
Survey.init(io);
});
survey.js:
var io = null;
var Survey = {};
Survey.init = function(socketio) {
io = socketio;
};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
module.exports = Survey;
This way it works, but I'm not happy passing io inside an init function to the required module.
What would be "the right way" to do this?
If I require('socket.io') inside the survey module, will it be the same instance as in index.js?
How would I even require that, since it needs the server, which needs the app, which is created in index.js?
I am confused and hope that somebody can help me. Thanks!
When you import a node.JS library you can also pass in objects. In your case the index.js file should be changed to the following:
//index.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey')(io);
Then just change your survey.js code to take the io object:
//survey.js
module.exports = function (io) {
var Survey = {};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
return Survey;
};
To answer your other question:
If you require('socket.io') inside the survey module, it will be a different instance from index.js.
EDIT
If you want a more modern way of doing it...You could use ES6 format and create a class to do this better:
'ES6 index.js
import SurveyClass from './Survey';
import * as express from 'express';
let app = express();
let server = require('http').createServer(app);
let io = require('socket.io')(server);
let MySurveyClass= SurveyClass(io);
let myInstance = new MySurveyClass();
myInstance.getCurrentQuestion(5, "some-socket-id");
'ES6 survey.js
export default class Survey{
constructor(io){
this.io= io;
};
getCurrentQuestion(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
this.io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
}
When you do this in multiple modules:
var socketio = require('socket.io');
then it will be the same object for all requires.
But if you do this:
var io = require('socket.io')(server);
even if you have the same object in server in both places, io would be a different value because it would come from different invocations of the function returned by require('socket.io') even though those functions would be the same.
If you want to make sure that the io is the same then you'd have do e.g. something like this: Make a module that exports a promise of io and some way to initialize it - a function that gets the server and everything needed. Now, in the place where you have the server you can require the module and initialize it with that exported function, and in other places you can import the module and use a promise.
Instead of a promise you could use callbacks or even just a property on the exported object that could be initially undefined and gets defined when the socket.io is initialized but using a promise would probably be most simple solution to make sure that you're not using it while it's not ready yet.
You didn't mention in your question whether or not you use some framework and which one if any, but some of the frameworks like Hapi give you an easy way to share functionality like that. E.g. see:
https://hapijs.com/tutorials/plugins
If you use Hapi then you should use plugins. If other framework then search for a similar feature.

How to set a variable to the result of morgan (not to log it on the console) in Node.js

I do not understand the stream in node well.
I try to save my app's request and response information to the mongodb.
Firstly, I want to set a variable to the result of morgan:
var apiInfo = morgan('dev')
app.use(console.log('test______',apiInfo))
However, it does not work. I know this in the morgan official site:
var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')
var app = express()
// create a write stream (in append mode)
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'})
// setup the logger
app.use(morgan('combined', {stream: accessLogStream}))
app.get('/', function (req, res) {
res.send('hello, world!')
})
But I do not want to save the result to the access.log, and I just want to save the result to a variable apiInfo.
use the project https://www.npmjs.com/package/mongo-morgan. Use regular expressions to modify the stream in the index.js , and then you can easily put Morgan's data to Mongodb

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?
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.

Using SocketIO in external lib for expressjs

my app.js is started with following code
var express = require("express"),
app = express(),
http = require('http'),
server = http.createServer(app),
io = require('socket.io').listen(server),
games = require("./lib/games");
Now I need to use socket.io in external lib which named games,how can I do that?
There are many ways to do this. One way is to have games export a function which accepts the socket.io object as a parameter.
For example:
// games.js
module.exports = function(io) { ... /* do something with io */ }
// app.js
var io = require('socket.io').listen(server),
games = require("./lib/games");
games(io);

Categories