Node.JS undefined is not a function on required module - javascript

I'm trying to use a class that I created called user.js. The code for this user is:
function User(){};
User.prototype.addUser = function(){
//Do stuff
return 0;
};
module.exports = User;
I'm including it in my index.js route file, which looks like this:
var config = require('../lib/config');
var db = require('../lib/db');
var User = require('../lib/user');
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
/* GET create user. */
router.get('/newuser', function(req, res, next) {
*****var newuser = User.addUser();*****
res.render('index', {
user: newuser
});
});
module.exports = router;
However, when I visit localhost/newuser, I get the following error: TypeError: undefined is not a function. This error is being thrown in index.js on the line I marked with 5 asterisks above.

You are defining a constructor named User() and exporting it. But, then when you require('../lib/user'), you get the constructor function, but you never construct a new object with it so you don't actually have an object of type User, you just have the constructor and thus there is no method addUser() on the constructor.
Instead of this:
var User = require('../lib/user');
you can call the constructor function like this:
var u = require('../lib/user');
var User = new u();
Or, if you never need to make another one, you can do it all in one line:
var User = new (require('../lib/user'))();

Another way would be to change your User.js class to return something on these lines...
function User(){};
User.prototype.addUser = function(){
//Do stuff
return 0;
};
module.exports = new User();

Related

nodejs variable scope issue

I have a nodejs route where I am trying to download a url as mp3 using npm-youtube-dl. I have a download directory that I watch with chokidar for files being added and when a file is added I save the link to the file and after the download finishes I call a function that's supposed to respond with the download URL using res.download. When the sendURL function is called the url that I can clearly see has been saved before is undefined when I console.log it... Any idea what i'm doing wrong here/how I can fix this? i'm guessing it's a js variable scope issue?
my code:
var express = require('express');
var router = express.Router();
var yt = require('youtube-dl');
var fs = require('fs');
var path = require('path');
var chokidar = require('chokidar');
var downloadPath = '';
var watcher = chokidar.watch('./downloads', {
ignored: '/^[^.]+$|\.(?!(part)$)([^.]+$)/',
persistent: true
});
watcher.on('add', function(path) {
console.log('added: ', path);
this.downloadPath = path;
console.log('saved', this.downloadPath);
});
/*
router.get('/', function(req, res, next) {
next();
});
*/
router.get('/', function(req, res) {
var url = 'https://soundcloud.com/astral-flowers-music/bella-flor';
var options = ['-x', '--audio-format', 'mp3', '-o', './downloads/%(title)s.%(ext)s'];
var video = yt.exec(url, options, {}, function exec(err, output) {
if (err) { throw err; }
console.log(output.join('\n'));
sendUrl();
});
function sendUrl() {
console.log(this.downloadPath);
//res.download(this.downloadPath);
}
});
module.exports = router;
You're misusing this. If you want to use the downloadPath variable in your functions, remove the this. from in front of them. this.downloadPath looks for a property called downloadPath on an object referenced by this, which is different from your module-global variable.
More: How does the "this" keyword work?
Even with that, you're relying on your add callback having been called before any client requests your / route, and you're returning the last value assigned to downloadPath by that add callback. I don't know enough about what you're doing to know whether that's correct, but the lack of coordination seems problematic.

Console Log URL Parameter in routes/index.js

I have the following URL:
http://localhost:3000/?url=test
In my routes/index.js I'm great the url parameter and trying to console.log:
var express = require('express');
var router = express.Router();
var url_param;
router.get('/:url', function (req, res) {
var url_param = req.params.url;
});
var url;
var url = url_param
console.log(url);
However it doesn't log anything. In my terminal I get it performing the GET function correctly:
GET /?url=test 304 4.169 ms - -
Am I missing something?
Thanks!
(I am guessing that this will work.) Try to write you console.log inside your function. Like
router.get('/:url', function (req, res) {
var url_param = req.params.url;
console.log(/* your code */ );
});
Here's how to store the value and use it somewhere else:
var express = require('express');
var router = express.Router();
var url;
// http://localhost:3000/url
router.get('/url', function(req, res) {
res.send("the stored url is " + url);
});
// http://localhost:3000/?url=x
router.get('/:url', function(req, res) {
url = req.params.url;
console.log(url);
res.send("url stored");
});
move the console.log() inside the route.get function.
Even though you have to move the console.log(); already inside your router function you declared a different variable var url_param by so doing they don't have same reference.
Why wouldn't it work outside the route.get function?
The moment you run 'node thisfile.js' everything on the script will be processed, however router.get function will be waiting to receive an event which will only be triggered once the url is visited.
Thus without the router.get function receiving an event url_param remains undefined. So to get the url param you need to visit the url it matches.
var express = require('express');
var router = express.Router();
var url_param;
router.get('/:url', function (req, res) {
url_param = req.params.url;
console.log(url_param);//TO BE HONEST This will work
});
console.log(url_param);//TO BE HONEST THIS WOULDNT WORK

How to export functions from modules in node.js

I am using node.js (v4.2.2) with express (4.13.1). I am trying to import my custom module functions to another module. Application is created with express, and only thing added to app.js is require for my route var tests = require('./routes/tests'); and app.use for that route app.use('/tests', tests);
My two custom files (modules) are (path is relative to project root):
./model/test.js
./routes/tests.js
Here is ./model/test.js:
var id;
var testNumber1;
var testNumber2;
function Test(id, testNumber1, testNumber2) {
this.id = id;
this.testNumber1 = testNumber1;
this.testNumber2 = testNumber2;
};
exports.reset = function() {
this.testNumber1 = 0;
this.testNumber2 = 0;
};
module.exports = Test;
And here is ./routes/tests.js:
var express = require('express');
var Red = require('../model/test.js');
var router = express.Router();
/*create new test :id*/
router.post('/:id', function(req, res, next) {
var myNewTest = new Red(req.params.id, 0, 0)
myNewTest.testNumber2 += 1;
myNewTest.reset();
res.send('id: ' + myNewTest.id +
' testNumber2: ' + myNewTest.testNumber2);
});
module.exports = router;
When I try to execute curl -X POST http://localhost:3000/tests/1 i get error TypeError: myNewTest.reset is not a function. I am having trouble understanding how to export functions correctly. If I understand this api reference correctly, to expose constructor of module, i have to use module.exports = Test;, but that doesn't expose reset function. So, to expose it I have declared it like exports.reset = function() {...}, but obviously, that doesn't work, at least not in my case.
Through some other answers I have also seen function being declared normally function reset() {...}, and exposed like exports.reset = reset;, which gives me the same error.
How do I expose reset function properly?
You should add it to the prototype, at the moment it's just a static method in your module, not attached to the Test constructor.
function Test(id, testNumber1, testNumber2) {
this.id = id;
this.testNumber1 = testNumber1;
this.testNumber2 = testNumber2;
};
Test.prototype.reset = function() {
this.testNumber1 = 0;
this.testNumber2 = 0;
};
module.exports = Test;

Creating a javascript object and binding this

I'm trying to build my first node app. My app.js file is shown below. I want to access this from aother module by doing 'app = require('app')'. I then want to access app.app, app.dbConn and app.models
The problem is that when I require this module, app.models is not present on the resulting object.
var express = require('express');
var path = require('path');
var orm = require('orm');
var settings = require('./config/settings');
var mainRouter = require('./config/routes');
var environment = require('./config/environment');
var db = require('./config/db');
var auth = require('./modules/auth');
module.exports = new function(){
this.app = express();
// middlewares must be added in order - start with the basics
environment(this.app);
if (process.env.TESTING) { dbSettings = settings.dbTesting; }
else { dbSettings = settings.db; }
// add models to the request early in the middleware chain
this.dbConn = orm.connect(dbSettings, function(err){
if (err) return console.error('DB Connection error: ' + err);
else{
this.models = db.init(this.dbConn);
this.app.use(function(req,res,next){
req.models = this.models;
next();
});
passport = auth.init(this.models);
authRouter = auth.router(passport)
this.app.use('/users', authRouter);
this.app.use(mainRouter);
}
}.bind(this));
this.app.listen(settings.port);
console.log('Server started... listening on port ' + settings.port)
}
The only way to implement what I wanted was with a function that takes a callback, in the end I rewrote my code thus:
var express = require('express');
var path = require('path');
var orm = require('orm');
var settings = require('./config/settings');
var mainRouter = require('./config/routes');
var environment = require('./config/environment');
var db = require('./config/db');
var auth = require('./modules/auth');
var app;
module.exports = function(cb){
app = express();
// middlewares must be added in order - start with the basics
environment(app);
if (process.env.TESTING) { dbSettings = settings.dbTesting; }
else { dbSettings = settings.db; }
// add models to the request early in the middleware chain
dbConn = orm.connect(dbSettings, function(err){
if (err) return console.error('DB Connection error: ' + err);
else{
models = db.init(dbConn);
app.use(function(req,res,next){
req.models = models;
next();
});
passport = auth.init(this.models);
authRouter = auth.router(passport)
app.use('/users', authRouter);
app.use(mainRouter);
cb({
dbConn: dbConn,
app: app,
models: models
});
}
});
}
if (!process.env.TESTING) {
module.exports(function(server){
server.app.listen(settings.port);
console.log('Server started... listening on port ' + settings.port)
});
}
app.models is defined only once database connection is completed: you cannot use it right away after requiring the module. You should provide an entry point that accepts a function to call once the connection is ready and call this function inside the orm.connect callback.
Even the "server started" message is a bit misleading as it's shown before the server can actually do anything because the function passed to orm.connect has not been called yet.
app.models is never defined so it is never available.
Instead, try
app.set('models', db.init(this.dbConn);

node.js export module function

I have a problem with node.js. I am creating a blog and I have two archives:
sessions.js users.js
in sessions.js :
function SessionsDAO(db) {
this.startSession = function(username, callback) {....}
}
module.exports.SessionsDAO = SessionsDAO;
in users.js
var Session = require('./sessions');
var s = new Session();
s.startSession(username);
but shows me error:
object is not a function
TypeError: object is not a function
require returns the exports object, so:
var SessionsDAO = require('./sessions').SessionsDAO;
var s = new SessionsDAO();
s.startSession(username);

Categories

Resources