Node 101: app.use ReferenceError [route] not defined - javascript

I am new to Node/Express, and have a basic question about routing as I am getting the following error message:
app.use('/edu', edu);
^
ReferenceError: edu is not defined
at Object.<anonymous> (/Users/ronitelman/Dropbox/happy/happy/app.js:29:17)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/Users/ronitelman/Dropbox/happy/happy/bin/www:7:11)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
[nodemon] app crashed - waiting for file changes before starting...
app.js:
app.use('/', routes);
app.use('/users', users);
app.use('/about', about);
app.use('/edu', edu);
File structure:
> root
> ...
> routes
| about.js
| edu.js
| index.js
| users.js
edu.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('dashboard', { layout: 'layout_edu' });
});
module.exports = router;
Additionally, I wanted to know if I should use the 'extends layout' in my dashboard.jade file, or if I should define the layout in the route
dashboard.jade
extends layout //- or res.render('dashboard', { layout: 'layout_edu' }); ?
block content
include ./nav/nav_layout.jade
.wrapper
include ./home/home.jade
include ./home/benefits.jade
include ./home/students.jade
include ./home/teachers.jade
include ./home/admin.jade
include ./home/analytics.jade
include ./home/tech.jade
include ./home/featured.jade

Make sure you require your edu module in your app.js file. Usually at the top of the file you would need something like var edu = require('./routes/edu.js'); (which asks node to load your edu.js file in the routes directory).
Concerning your second question, the way you make your extends call in your Jade file should be OK. For more clarity and to avoid mistakes, you should reference it by its filename, like extends ./layout.jade (if layout.jade is in the same directory as dashboard.jade)

Related

Mammoth not finding any modules

I am trying to create a Word to HTML converter, and I am trying to use Mammoth as a framework. Whenever I run my script, I get:
Internal/modules/cjs/loader.js:983
throw err;
^
Error: Cannot find module 'mammoth'
Require stack:
- C:\Users\magnu\OneDrive\Documents\GitHub\work_app\app.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:980:15)
at Function.Module._load (internal/modules/cjs/loader.js:862:27)
at Module.require (internal/modules/cjs/loader.js:1042:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object.<anonymous> (C:\Users\magnu\OneDrive\Documents\GitHub\work_app\app.js:4:15)
at Module._compile (internal/modules/cjs/loader.js:1156:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ 'C:\\Users\\magnu\\OneDrive\\Documents\\GitHub\\work_app\\app.js' ]
}
This is the code for my app.js
// Requirements
var express = require('express'),
ejs = require('ejs'),
mammoth = require('mammoth')
var app = express();
app.set('view engine', 'ejs');
// Mammoth
mammoth.convertToHtml({path: "../../../../Downloads/Federal Gov't - Debate Sheet.docx"})
.then(function(result){
var html = result.value; // The generated HTML
var messages = result.messages; // Any messages, such as warnings during conversion
})
.done();
app.get('/', function (req, res) {
res.render('landing');
})
app.listen(4009, function () {
console.log("Server ready on PORT 4009");
})
If anyone knows the solution to my problem, please post below.
For all of my code, go to Github
The answer to this is very simple. Just make sure you have installed the package.
But I am sure I have already installed the package. What now?
My next course of action is to make sure you have it under dependencies in the package.json file you store other dependencies in. To automate this process, create a GitHub page and start commiting to it. This can speed up your development process by months simply because other people are able to help you.
If those don't work, ask a question and comment it to me and I might be able to help!

Module not found unless I use a complete path when creating plugins in Hapi

I'm trying to familiarise myself with HapiJS and have been playing around with it this week, I've run into a problem with plugins and paths. I get an error regarding the path I specify when I require a file. I can't use " ./ " without getting an error. The only way to overcome the error is to use the full complete path.
Here's my code that works:
'use strict';
const indexController = require('/Users/mylaptop/docker-node/controllers/IndexController.js');
module.exports.plugin = {
name: 'myPlugin',
version: '1.0.0',
register: async function (server, options) {
// Create a route for example
server.route({
method:'GET',
path:'/test',
handler: function (request, h) {
return indexController.loadIndex(h);
}
});
}
};
However, if I try to require my IndexController file this way:
const indexController = require('./controllers/IndexController.js');
Then I get this error:
internal/modules/cjs/loader.js:583
throw err;
^
Error: Cannot find module '/Users/mylaptop/docker-node/Users/mylaptop/docker-node/controllers/IndexController.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.<anonymous> (/Users/mylaptop/docker-node/config/routes/index.js:5:25)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
It doesn't work inside of my plugin, yet outside of my plugin, requiring files this way works fine.
What could be the problem? How can I solve it?
Thanks in advance.
Problem solved with:
const indexController = require('../../controllers/IndexController.js');
My project root folder was 2 directories away, hence ../../ working for me.

TypeError: fn is not a function. Difference between two functions in module.exports

I'm trying to use function from other file to make asyn/await wrap for routing. Details:
everything works without wrap function
second func with time works fine with similar code of export
wrap function works fine when located in users file
Question: What have I missed and how make wrap work from server file? Thanks for hint in advance.
server.js
let express = require('express');
let userRules = require('./private/routes/users');
app.use('/user', userRules);
function asyncWrap(fn) {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
}
function getCurrentTime() {
return getDateTime(); //inner func
}
exports.getCurrentTime= getCurrentTime;
exports.asyncWrap = asyncWrap;
users.js
let express = require('express');
let router = express.Router();
const server = require('../../server');
router.post('/auth', server.asyncWrap(async (req, res, next) => { //this line throws error
let user = await sql.getUserByEmail(req.body.email);
console.log(server.getCurrentTime()+req.body.email+" tried to auth"); // this works
...
}));
Error
TypeError: server.asyncWrap is not a function
18|dev | at Object.<anonymous> (/var/www/gowarranty/serverNode/forfun/private/routes/users.js:145:54)
18|dev | at Module._compile (module.js:571:32)
18|dev | at Object.Module._extensions..js (module.js:580:10)
18|dev | at Module.load (module.js:488:32)
18|dev | at tryModuleLoad (module.js:447:12)
18|dev | at Function.Module._load (module.js:439:3)
18|dev | at Module.require (module.js:498:17)
18|dev | at require (internal/module.js:20:19)
18|dev | at Object.<anonymous> (/var/www/gowarranty/serverNode/forfun/private/routes/index.js:11:13)
18|dev | at Module._compile (module.js:571:32)
18|dev | at Object.Module._extensions..js (module.js:580:10)
18|dev | at Module.load (module.js:488:32)
18|dev | at tryModuleLoad (module.js:447:12)
18|dev | at Function.Module._load (module.js:439:3)
18|dev | at Module.require (module.js:498:17)
18|dev | at require (internal/module.js:20:19)
18|dev | at Object.<anonymous> (/var/www/gowarranty/serverNode/forfun/server.js:5:14)
18|dev | at Module._compile (module.js:571:32)
18|dev | at Object.Module._extensions..js (module.js:580:10)
18|dev | at Module.load (module.js:488:32)
18|dev | at tryModuleLoad (module.js:447:12)
18|dev | at Function.Module._load (module.js:439:3)
18|dev | at Object.<anonymous> (/usr/lib/node_modules/pm2/lib/ProcessContainerFork.js:78:21)
18|dev | at Module._compile (module.js:571:32)
18|dev | at Object.Module._extensions..js (module.js:580:10)
18|dev | at Module.load (module.js:488:32)
18|dev | at tryModuleLoad (module.js:447:12)
18|dev | at Function.Module._load (module.js:439:3)
18|dev | at Module.runMain (module.js:605:10)
18|dev | at run (bootstrap_node.js:427:7)
18|dev | at startup (bootstrap_node.js:151:9)
18|dev | at bootstrap_node.js:542:3
tl;dr
you have a circular dependency issue. server.js requires users.js and users.js again requires the server.js.
The way nodeJS modules work, the require() call loads the file, and executes it after wrapping it in a function, passing it the module, exports and some other parameters. The module/exports is already cached for the module name, even before the file execution is complete. After execution the code in your file ends up assigning various objects associated with keys on module.exports or exports.
Now, in your case, the execution starts from server.js which requires users.js on line 2. The control passes on to users.js which requires server.js again on line 3. Then tries to call server.asyncWrap, but that key would be assigned to exports only on line 14 in server.js. The control for that file is still blocked on line 2. Hence accessing the key returns undefined (which is not a function).
There are multiple ways you can solve this.
One) You can design your code in such a manner that there are no circular dependencies. Perhaps by moving your asyncWrap function to a helper file elsewhere.
Two) You can move line two and three from server.js to end of the file, new file should look something like this:
let express = require('express');
function asyncWrap(fn) {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
}
function getCurrentTime() {
return getDateTime(); //inner func
}
exports.getCurrentTime= getCurrentTime;
exports.asyncWrap = asyncWrap;
let userRules = require('./private/routes/users');
app.use('/user', userRules);`
While the second option would work too, I would strongly suggest using the first option.
module.exports It is the object reference that gets returned from the require() calls.
exports is just a convenience variable so module authors can write less code
Read this article. You will have a better understanding about creating your own modules and working with node.

TypeError: Router.use() requires middleware function but got a Object in Express 4.13.1

This is how it is configured in my express 4.13.1 application
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
-------------------------------------
app.js
var routes = require('./routes/index');
app.use('/', routes);
app.use('api/users', users);
Even after this configuration it still throws the error. any ideas?
/home/vagrant/portal-api/portal-api/node_modules/express/lib/router/index.js:458
throw new TypeError('Router.use() requires middleware function but got a
^
TypeError: Router.use() requires middleware function but got a Object
at Function.use (/home/vagrant/portal-api/portal-api/node_modules/express/lib/router/index.js:458:13)
at EventEmitter.<anonymous> (/home/vagrant/portal-api/portal-api/node_modules/express/lib/application.js:219:21)
at Array.forEach (native)
at EventEmitter.use (/home/vagrant/portal-api/portal-api/node_modules/express/lib/application.js:216:7)
at Object.<anonymous> (/home/vagrant/portal-api/portal-api/app.js:31:5)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

Error running express with node

I'm trying to start a very simple server on my Mac so I can access a file from localhost.
I have node and express installed and this is all that it is in my server file.
var express = require('express'),
app = express();
app.use(express.static(__dirname, '/'));
app.listen(8080);
console.log("App listening on port 8080");
When I try to do:
node server
I get this as a response:
/Users/mt_slasher/node_modules/express/node_modules/serve-static/index.js:47
var opts = Object.create(options || null)
^
TypeError: Object prototype may only be an Object or null: /
at Function.create (native)
at Function.serveStatic (/Users/mt_slasher/node_modules/express/node_modules/serve-static/index.js:47:21)
at Object.<anonymous> (/Users/mt_slasher/Desktop/My Projects/Basket/Site/server.js:4:23)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
I've run this same file on a Windows machine with the same files and had no problem.
After some digging, I found this line seems to be the main culprit:
app.use(express.static(__dirname, '/'));
Can someone tell me what might be happening?
That is because you are passing "/" as second parameter (options)
app.use(express.static(__dirname + '/'));
See serve-static:
function serveStatic(root, options) ...
https://github.com/expressjs/serve-static/blob/master/index.js
Also note that it would be better to use a different directory than your root e.g. express.static(__dirname + '/public') to avoid exposing your root.
express.static is used to define directory where your "static" files reside look at here for more info.
It accepts only a string with the path you want to be static:
So your code should be:
app.use(express.static('/'));
Or
app.use(express.static(__dirname + '/'));
But that doesn't make much sense, imho.
Remove the line or define the real path where your assets files are.
The second parameter you are passing to express.static is incorrect. remove the second parameter.
app.use(express.static(__dirname));

Categories