include external .js file in node.js app - javascript

I have an app.js node application. As this file is starting to grow, I would like to move some part of the code in some other files that I would "require" or "include" in the app.js file.
I'm trying things like:
// Declare application
var app = require('express').createServer();
// Declare usefull stuff for DB purposes
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
// THE FOLLOWING REQUIRE DOES NOT WORK
require('./models/car.js');
in car.js:
// Define Car model
CarSchema = new Schema({
brand : String,
type : String
});
mongoose.model('Car', CarSchema);
I got the error:
ReferenceError: Schema is not defined
I'm just looking to have the content of car.js loaded (instead of having everything in the same app.js file) Is there a particuliar way to do this in node.js ?

To place an emphasis on what everyone else has been saying var foo in top level does not create a global variable. If you want a global variable then write global.foo. but we all know globals are evil.
If you are someone who uses globals like that in a node.js project I was on I would refactor them away for as there are just so few use cases for this (There are a few exceptions but this isn't one).
// Declare application
var app = require('express').createServer();
// Declare usefull stuff for DB purposes
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
require('./models/car.js').make(Schema, mongoose);
in car.js
function make(Schema, mongoose) {
// Define Car model
CarSchema = new Schema({
brand : String,
type : String
});
mongoose.model('Car', CarSchema);
}
module.exports.make = make;

The correct answer is usually to use require, but in a few cases it's not possible.
The following code will do the trick, but use it with care:
var fs = require('fs');
var vm = require('vm');
var includeInThisContext = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
}.bind(this);
includeInThisContext(__dirname+"/models/car.js");

Short answer:
// lib.js
module.exports.your_function = function () {
// Something...
};
// app.js
require('./lib.js').your_function();

you can put
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
at the top of your car.js file for it to work, or you can do what Raynos said to do.

If you just want to test a library from the command line, you could do:
cat somelibrary.js mytestfile.js | node

This approach works for me in Node.js, Is there any problem with this one?
File 'include.js':
fs = require('fs');
File 'main.js':
require('./include.js');
fs.readFile('./file.json', function (err, data) {
if (err) {
console.log('ERROR: file.json not found...')
} else {
contents = JSON.parse(data)
};
})

Related

Sequelize TypeError: defineCall is not a function

Working on an express project with a SQLite database.
I'm getting an Sequelize TypeError that I've been working on for hours but I'm coming up against a brick wall:
C:\-----\node_modules\sequelize\lib\sequelize.js:392
this.importCache[path] = defineCall(this, DataTypes);
^
TypeError: defineCall is not a function
at Sequelize.import (C:\----\node_modules\sequelize\lib\sequelize.js:392:32)
at C:\----\models\index.js:25:32
After doing some research, it appears that this could be caused when trying to import a non-sequelize object. Below is the problematic index.js file.
index.js:
var Sequelize = require('sequelize');
var config = {
dialect: 'sqlite',
storage: 'library.db'
};
var connection = new Sequelize(config);
var contents = fs.readdirSync(__dirname);
var db = {};
contents = contents.filter(function(file){
var currFileName = __filename.split('/');
var checkOne = file.substr(file.length - 3, 3) === '.js';
var checkTwo = file !== currFileName[currFileName.length - 1];
return checkOne && checkTwo;
});
contents.forEach(function(file){
var path = [__dirname, file].join('/');
var model = connection.import(path);
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName){
var model = db[modelName];
if(model.associate) {
model.associate(db);
}
});
module.exports = {
models: db,
connection: connection
};
I do not have any function called defineCall, any idea where the error is coming from?
This is indeed caused by importing a file that's not a Sequelize model. In my case, it was because my index.js was pulling in my test files as well as the models, which were in the same directory. Try adding another check like checkOne to exclude anything that ends with .test.js.
With the hint from the answer by #Floppy, I got to realise that it would be better if we stored those related files encapsulated in a folder.
For eg. make a folder named Models and store your index.js with all the models (eg. User model, photos model, etc) and then try.
Thanks.

How do I add temporary properties on a mongoose object just for response, which is not stored in database

I would like to fill a couple of extra temporary properties with additional data and send back to the response
'use strict';
var mongoose = require('mongoose');
var express = require('express');
var app = express();
var TournamentSchema = new mongoose.Schema({
createdAt: { type: Date, default: Date.now },
deadlineAt: { type: Date }
});
var Tournament = mongoose.model('Tournament', TournamentSchema);
app.get('/', function(req, res) {
var tournament = new Tournament();
// Adding properties like this 'on-the-fly' doesnt seem to work
// How can I do this ?
tournament['friends'] = ['Friend1, Friend2'];
tournament.state = 'NOOB';
tournament.score = 5;
console.log(tournament);
res.send(tournament);
});
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
But the properties wont get added on the Tournament object and therefor not in the response.
Found the answer here: Unable to add properties to js object
I cant add properties on a Mongoose object, I have to convert it to plain JSON-object using the .toJSON() or .toObject() methods.
EDIT: And like #Zlatko mentions, you can also finalize your queries using the .lean() method.
mongooseModel.find().lean().exec()
... which also produces native js objects.

Node.js - how to use external library (VersionOne JS SDK)?

I'm trying to use VersionOne JS SDK in Node.js (https://github.com/versionone/VersionOne.SDK.JavaScript). I'm simply downloading whole library, placing it alongside with my js file:
var v1 = require('./v1sdk/v1sdk.js');
var V1Server = v1.V1Server;
console.log(v1);
console.log(V1Server);
Unfortunately something seems wrong, the output I get after calling
node app.js
is:
{}
undefined
Can somebody point me what I'm doing wrong or check whether the sdk is valid.
Thanks!
You can see in the source where V1Server is defined, that it's a class with a constructor. So you need to use the new keyword and pass the arguments for your environment.
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/client.coffee#L37
var server = new V1Server('cloud'); //and more if you need
Can you try the sample.js script that I just updated from here:
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/sample.js
It pulls in the two modules like this:
var V1Meta = require('./v1meta').V1Meta;
var V1Server = require('./client').V1Server;
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new V1Server(hostname, instance, username, password, port, protocol);
var v1 = new V1Meta(server);
v1.query({
from: "Member",
where: {
IsSelf: 'true'
},
select: ['Email', 'Username', 'ID'],
success: function(result) {
console.log(result.Email);
console.log(result.Username);
console.log(result.ID);
},
error: function(err) { // NOTE: this is not working correctly yet, not called...
console.log(err);
}
});
You might have to get the latest and build the JS from CoffeeScript.
I think I was trying out "browserify" last year and that's how the "v1sdk.js" file got generated. But I'm not sure if that's the best approach if you're using node. It's probably better just to do it the way the sample.js file is doing it.
However, I did also check in a change to v1sdk.coffee which property exports the two other modules, just as a convenience. With that, you can look at sample2.js. The only different part there is this, which is more like you were trying to do with your example:
var v1sdk = require('./v1sdk');
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new v1sdk.V1Server(hostname, instance, username, password, port, protocol);
var v1 = new v1sdk.V1Meta(server);

Syntax in express app

The following snippet is from some auto generated express code:
//Load configurations
//if test env, load example file
var env = process.env.NODE_ENV || 'development',
config = require('./config/config')[env],
auth = require('./config/middlewares/authorization'),
mongoose = require('mongoose');
[env] is confusing and doesn't look like valid javascript to me. How can you call a function like that?
require('./config/config')[env]
require is a function call. It appears to return an object. It is referencing a property of that object.
Does it make more sense if it was written as
var env = process.env.NODE_ENV || 'development';
var req = require('./config/config');
var config = req[env];

How to use a MongoDB collection in another file

I have one server file that is server.js.
I have a MongoDB connection inside this file like this:
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
I have another file named server2.js. In this file I have to check if a username exists or not from Ucollection (this is collection name).
How can I give the MongoDB connection to server2.js? How can I use this collection in server2.js?
You could do something like this
in server.js:
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
global.mongoHelper = {};
global.mongoHelper.db = Db;
global.mongoHelper.bson = BSON;
global.mongoHelper.server = Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
in server2.js
client=new global.mongoHelper.db('database' , new global.mongoHelper.server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
I think much cleaner way of doing this is to seprate your database configration into seprate file. Like this
in database-config.js
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
module.exports.connectDatabase = function(callback){
client.open(function(err,pClient)
{
if(err){
console.log(err);
process.exit(1);
}
module.exports.userCollection = pClient.collection('userdetails');
callback();
});
}
in server.js
var database = require('./database-config')
database.connectDatabase(function() {
//here you can reuse collection like this
database.userCollection
}
in server2.js
var database = require('./database-config')
//here you can reuse collection like this
database.userCollection
I am assuming that server.js is your main file which actually intiate server so when you run your application it connects to database and load required collections which you can use anywhere in your application like I did this is considered as best practice to re-use collections. Let me know if there is any confusion
Well you are a bit mistaken about the whole concept of modularizing the code. For your task, you should not make a second server.js. You can make another module say, verifyUser and require it in your server.js file. You may require it (may be) after your mongodb connection.
server.js
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
exports.Ucollection=pClient;
});
});
server2.js
var mongodb = require('mongodb');
var mainApp=require('./server');
var collectionObj=mainApp.Ucollection;
var collection = new mongodb.Collection(collectionObj, 'userdetails');
Using this collection.you can query like below
collection.insert(userInfo,{safe:true},function(err, objects) {
if(!err){
console.log('Data inserted successfully.');
}
});

Categories

Resources