Syntax in express app - javascript

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];

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.

Multitenant configuration data for the SDK Library

This question builds on an answer to a previous question, where I was looking for a solution to share configuration data between actors (nodejs modules) of a system (SDK) without using Factory pattern.
This time I need to make the SDK multi-tenant by providing different configuration data for distinct SDK instances.
app.js
var SDKAcctA = require("./sdk");
SDKAcctA.config = {key: "key", secret: "secret"};
var SDKAcctB = require("./sdk");
SDKAcctB.config = {key: "key2", secret: "secret2"};
// use both of them concurrently without each one overriding the config data of the other
var mA = new SDKAcctA.M1();
mA.doSomething();
var mB = new SDKAcctB.M1();
mB.doSomething();
sdk.js
var SDK = function(){};
SDK.config = {key: null, secret: null};
module.exports = SDK;
require("./m1"); //executing other modules to make it work
m1.js
var SDK = require("./sdk");
var M1 = function(){};
M1.prototype.doSomething = function(){
var config = SDK.config //getting access to main module's config data
};
SDK.M1 = M1;
Question:
Right now the configuration data is getting overriden by the other instance and that's what the issue is. Please advise.

"not found" plaintext in browser, when trying to render template with swig on koajs

I am using koajs on node.js and the swig templating engine to learn and code a web service. At the moment the Browser only loads up the words 'not found'. The code worked before i tried to split the program up into multiple files. After then i tried to get it work, even with getting everything back together in one file, without success.
The html file at './templates/base.html' does exist.
For clarification, when I run 'node --harmony index.js' there are no errors and I do get the output 'listening on port 3000'. But when I try to load up the page in my browser, i get the plain text 'not found'.
Here are my files:
index.js:
var routes = require('./routes');
var server = require('./server');
routes.baseroute
server.init(3000);
server.js:
var serve = require('koa-static');
var koa = require('koa');
var app = koa();
var init = function(port){
app.use(serve('./public'));
app.listen(port);
console.log('\n ---> listening on port '+port);
};
exports.init = init;
routes.js:
var koa = require('koa');
var route = require('koa-route');
var views = require('./views');
var app = koa();
var baseroute = app.use(route.get('/', views.baseview));
exports.baseroute = baseroute;
views.js:
var swig = require('swig');
var data = require('./data');
var baseview = function*(){
var tpl = swig.compileFile('./templates/base.html');
this.body = tpl(data.basedata);
};
exports.baseview = baseview;
data.js:
var basedata = {user: 'testuser123'};
exports.basedata = basedata;
So what's really happening is after you split them into their own files you created a separate instance of koa in their own file.
See:-
var app = koa();
in both server.js and routes.js and koa thinks of them as separate apps. It's possible in koa to have more than one apps but you'd have to mount them for them to have any kind of linkage.
First, find the main file that you want your linkage to happen. I'm guessing it's server.js and expose other app from their file(route.js). Now when you're linking them just use mount('/', require('./routes')); and koa will link them as one unit. In short:-
//routes.js
var koa = require('koa');
...
...
var app = koa();
app.use(route.get('/', views.baseview));
module.exports = app;
//server.js
var app = require('koa');
var mount = require('koa-mount');
var routes = require('./routes');
...
...
var init = function(port){
app.use(serve('./public'));
app.use(mount('/route', routes));
app.listen(port);
console.log('\n ---> listening on port '+port);
};
exports.init = init;

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);

include external .js file in node.js app

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)
};
})

Categories

Resources